Task #3538: Add tribe_gig PickledObjectField attribute to UserStory model

remotes/origin/logger
David Barragán Merino 2015-11-26 18:47:25 +01:00
parent 3ba759e5d1
commit fd12f84969
10 changed files with 86 additions and 20 deletions

View File

@ -11,6 +11,7 @@
- Improve login and forgot password: allow username or email case-insensitive if the query only - Improve login and forgot password: allow username or email case-insensitive if the query only
match with one user. match with one user.
- Improve the django admin panel, now it is more usable and all the selector fields works properly. - Improve the django admin panel, now it is more usable and all the selector fields works properly.
- [API] Add tribe_gig field to user stories (improve integration between Taiga and Taiga Tribe).
- [API] Performance improvements for project stats. - [API] Performance improvements for project stats.
- Lots of small and not so small bugfixes. - Lots of small and not so small bugfixes.

View File

@ -84,6 +84,19 @@ class PgArrayField(serializers.WritableField):
return data return data
class PickledObjectField(serializers.WritableField):
"""
PickledObjectField objects serializer.
"""
widget = widgets.Textarea
def to_native(self, obj):
return obj
def from_native(self, data):
return data
class TagsField(serializers.WritableField): class TagsField(serializers.WritableField):
""" """
Pickle objects serializer. Pickle objects serializer.

View File

@ -76,6 +76,23 @@ class ProjectViewSet(LikedResourceMixin, HistoryResourceMixin, ModelCrudViewSet)
return qs return qs
def get_serializer_class(self):
if self.action == "list":
return self.list_serializer_class
elif self.action == "create":
return self.serializer_class
if self.action == "by_slug":
slug = self.request.QUERY_PARAMS.get("slug", None)
project = get_object_or_404(models.Project, slug=slug)
else:
project = self.get_object()
if permissions_service.is_project_owner(self.request.user, project):
return self.admin_serializer_class
return self.serializer_class
@detail_route(methods=["POST"]) @detail_route(methods=["POST"])
def watch(self, request, pk=None): def watch(self, request, pk=None):
project = self.get_object() project = self.get_object()
@ -105,23 +122,6 @@ class ProjectViewSet(LikedResourceMixin, HistoryResourceMixin, ModelCrudViewSet)
services.update_projects_order_in_bulk(data, "user_order", request.user) services.update_projects_order_in_bulk(data, "user_order", request.user)
return response.NoContent(data=None) return response.NoContent(data=None)
def get_serializer_class(self):
if self.action == "list":
return self.list_serializer_class
elif self.action == "create":
return self.serializer_class
if self.action == "by_slug":
slug = self.request.QUERY_PARAMS.get("slug", None)
project = get_object_or_404(models.Project, slug=slug)
else:
project = self.get_object()
if permissions_service.is_project_owner(self.request.user, project):
return self.admin_serializer_class
return self.serializer_class
@list_route(methods=["GET"]) @list_route(methods=["GET"])
def by_slug(self, request): def by_slug(self, request):
slug = request.QUERY_PARAMS.get("slug", None) slug = request.QUERY_PARAMS.get("slug", None)

View File

@ -286,6 +286,7 @@ def userstory_freezer(us) -> dict:
"blocked_note": us.blocked_note, "blocked_note": us.blocked_note,
"blocked_note_html": mdrender(us.project, us.blocked_note), "blocked_note_html": mdrender(us.project, us.blocked_note),
"custom_attributes": extract_user_story_custom_attributes(us), "custom_attributes": extract_user_story_custom_attributes(us),
"tribe_gig": us.tribe_gig,
} }
return snapshot return snapshot

View File

@ -9,7 +9,8 @@
"kanban_order", "kanban_order",
"taskboard_order", "taskboard_order",
"us_order", "us_order",
"custom_attributes" "custom_attributes",
"tribe_gig",
] %} ] %}
{% for field_name, values in changed_fields.items() %} {% for field_name, values in changed_fields.items() %}

View File

@ -9,7 +9,8 @@
"us_order", "us_order",
"blocked_note_diff", "blocked_note_diff",
"blocked_note_html", "blocked_note_html",
"custom_attributes" "custom_attributes",
"tribe_gig",
] %} ] %}
{% for field_name, values in changed_fields.items() %} {% for field_name, values in changed_fields.items() %}
{% if field_name not in excluded_fields %} {% if field_name not in excluded_fields %}

View File

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
import picklefield.fields
class Migration(migrations.Migration):
dependencies = [
('userstories', '0010_remove_userstory_watchers'),
]
operations = [
migrations.AddField(
model_name='userstory',
name='tribe_gig',
field=picklefield.fields.PickledObjectField(editable=False, null=True, default=None, verbose_name='taiga tribe gig', blank=True),
),
]

View File

@ -21,6 +21,7 @@ from django.utils.translation import ugettext_lazy as _
from django.utils import timezone from django.utils import timezone
from djorm_pgarray.fields import TextArrayField from djorm_pgarray.fields import TextArrayField
from picklefield.fields import PickledObjectField
from taiga.base.tags import TaggedMixin from taiga.base.tags import TaggedMixin
from taiga.projects.occ import OCCModelMixin from taiga.projects.occ import OCCModelMixin
@ -101,6 +102,10 @@ class UserStory(OCCModelMixin, WatchedModelMixin, BlockedMixin, TaggedMixin, mod
related_name="generated_user_stories", related_name="generated_user_stories",
verbose_name=_("generated from issue")) verbose_name=_("generated from issue"))
external_reference = TextArrayField(default=None, verbose_name=_("external reference")) external_reference = TextArrayField(default=None, verbose_name=_("external reference"))
tribe_gig = PickledObjectField(null=True, blank=True, default=None,
verbose_name="taiga tribe gig")
_importing = None _importing = None
class Meta: class Meta:

View File

@ -17,6 +17,7 @@
from django.apps import apps from django.apps import apps
from taiga.base.api import serializers from taiga.base.api import serializers
from taiga.base.fields import TagsField from taiga.base.fields import TagsField
from taiga.base.fields import PickledObjectField
from taiga.base.fields import PgArrayField from taiga.base.fields import PgArrayField
from taiga.base.neighbors import NeighborsSerializerMixin from taiga.base.neighbors import NeighborsSerializerMixin
from taiga.base.utils import json from taiga.base.utils import json
@ -45,7 +46,8 @@ class RolePointsField(serializers.WritableField):
return json.loads(obj) return json.loads(obj)
class UserStorySerializer(WatchersValidator, VoteResourceSerializerMixin, EditableWatchedResourceModelSerializer, serializers.ModelSerializer): class UserStorySerializer(WatchersValidator, VoteResourceSerializerMixin, EditableWatchedResourceModelSerializer,
serializers.ModelSerializer):
tags = TagsField(default=[], required=False) tags = TagsField(default=[], required=False)
external_reference = PgArrayField(required=False) external_reference = PgArrayField(required=False)
points = RolePointsField(source="role_points", required=False) points = RolePointsField(source="role_points", required=False)
@ -59,6 +61,7 @@ class UserStorySerializer(WatchersValidator, VoteResourceSerializerMixin, Editab
status_extra_info = BasicUserStoryStatusSerializer(source="status", required=False, read_only=True) status_extra_info = BasicUserStoryStatusSerializer(source="status", required=False, read_only=True)
assigned_to_extra_info = UserBasicInfoSerializer(source="assigned_to", required=False, read_only=True) assigned_to_extra_info = UserBasicInfoSerializer(source="assigned_to", required=False, read_only=True)
owner_extra_info = UserBasicInfoSerializer(source="owner", required=False, read_only=True) owner_extra_info = UserBasicInfoSerializer(source="owner", required=False, read_only=True)
tribe_gig = PickledObjectField(required=False)
class Meta: class Meta:
model = models.UserStory model = models.UserStory

View File

@ -514,3 +514,24 @@ def test_update_userstory_remove_watchers(client):
assert response.data["watchers"] == [] assert response.data["watchers"] == []
watcher_ids = list(us.get_watchers().values_list("id", flat=True)) watcher_ids = list(us.get_watchers().values_list("id", flat=True))
assert watcher_ids == [] assert watcher_ids == []
def test_update_userstory_update_tribe_gig(client):
project = f.ProjectFactory.create()
us = f.UserStoryFactory.create(project=project, status__project=project, milestone__project=project)
f.MembershipFactory.create(project=us.project, user=us.owner, is_owner=True)
url = reverse("userstories-detail", kwargs={"pk": us.pk})
data = {
"tribe_gig": {
"id": 2,
"title": "This is a gig test title"
},
"version":1
}
client.login(user=us.owner)
response = client.json.patch(url, json.dumps(data))
assert response.status_code == 200
assert response.data["tribe_gig"] == data["tribe_gig"]