Skip to content

Commit

Permalink
Task #3538: Add tribe_gig PickledObjectField attribute to UserStory m…
Browse files Browse the repository at this point in the history
…odel
  • Loading branch information
bameda committed Nov 30, 2015
1 parent 3ba759e commit fd12f84
Show file tree
Hide file tree
Showing 10 changed files with 86 additions and 20 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
- Improve login and forgot password: allow username or email case-insensitive if the query only
match with one user.
- 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.
- Lots of small and not so small bugfixes.

Expand Down
13 changes: 13 additions & 0 deletions taiga/base/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,19 @@ def from_native(self, 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):
"""
Pickle objects serializer.
Expand Down
34 changes: 17 additions & 17 deletions taiga/projects/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,23 @@ def get_queryset(self):

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"])
def watch(self, request, pk=None):
project = self.get_object()
Expand Down Expand Up @@ -105,23 +122,6 @@ def bulk_update_order(self, request, **kwargs):
services.update_projects_order_in_bulk(data, "user_order", request.user)
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"])
def by_slug(self, request):
slug = request.QUERY_PARAMS.get("slug", None)
Expand Down
1 change: 1 addition & 0 deletions taiga/projects/history/freeze_impl.py
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,7 @@ def userstory_freezer(us) -> dict:
"blocked_note": us.blocked_note,
"blocked_note_html": mdrender(us.project, us.blocked_note),
"custom_attributes": extract_user_story_custom_attributes(us),
"tribe_gig": us.tribe_gig,
}

return snapshot
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
"kanban_order",
"taskboard_order",
"us_order",
"custom_attributes"
"custom_attributes",
"tribe_gig",
] %}

{% for field_name, values in changed_fields.items() %}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
"us_order",
"blocked_note_diff",
"blocked_note_html",
"custom_attributes"
"custom_attributes",
"tribe_gig",
] %}
{% for field_name, values in changed_fields.items() %}
{% if field_name not in excluded_fields %}
Expand Down
20 changes: 20 additions & 0 deletions taiga/projects/userstories/migrations/0011_userstory_tribe_gig.py
Original file line number Diff line number Diff line change
@@ -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),
),
]
5 changes: 5 additions & 0 deletions taiga/projects/userstories/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
from django.utils import timezone

from djorm_pgarray.fields import TextArrayField
from picklefield.fields import PickledObjectField

from taiga.base.tags import TaggedMixin
from taiga.projects.occ import OCCModelMixin
Expand Down Expand Up @@ -101,6 +102,10 @@ class UserStory(OCCModelMixin, WatchedModelMixin, BlockedMixin, TaggedMixin, mod
related_name="generated_user_stories",
verbose_name=_("generated from issue"))
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

class Meta:
Expand Down
5 changes: 4 additions & 1 deletion taiga/projects/userstories/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from django.apps import apps
from taiga.base.api import serializers
from taiga.base.fields import TagsField
from taiga.base.fields import PickledObjectField
from taiga.base.fields import PgArrayField
from taiga.base.neighbors import NeighborsSerializerMixin
from taiga.base.utils import json
Expand Down Expand Up @@ -45,7 +46,8 @@ def from_native(self, obj):
return json.loads(obj)


class UserStorySerializer(WatchersValidator, VoteResourceSerializerMixin, EditableWatchedResourceModelSerializer, serializers.ModelSerializer):
class UserStorySerializer(WatchersValidator, VoteResourceSerializerMixin, EditableWatchedResourceModelSerializer,
serializers.ModelSerializer):
tags = TagsField(default=[], required=False)
external_reference = PgArrayField(required=False)
points = RolePointsField(source="role_points", required=False)
Expand All @@ -59,6 +61,7 @@ class UserStorySerializer(WatchersValidator, VoteResourceSerializerMixin, Editab
status_extra_info = BasicUserStoryStatusSerializer(source="status", 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)
tribe_gig = PickledObjectField(required=False)

class Meta:
model = models.UserStory
Expand Down
21 changes: 21 additions & 0 deletions tests/integration/test_userstories.py
Original file line number Diff line number Diff line change
Expand Up @@ -514,3 +514,24 @@ def test_update_userstory_remove_watchers(client):
assert response.data["watchers"] == []
watcher_ids = list(us.get_watchers().values_list("id", flat=True))
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"]

0 comments on commit fd12f84

Please sign in to comment.