Task #3538: Add tribe_gig PickledObjectField attribute to UserStory model
parent
3ba759e5d1
commit
fd12f84969
|
@ -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.
|
||||
|
||||
|
|
|
@ -84,6 +84,19 @@ class PgArrayField(serializers.WritableField):
|
|||
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.
|
||||
|
|
|
@ -76,6 +76,23 @@ class ProjectViewSet(LikedResourceMixin, HistoryResourceMixin, ModelCrudViewSet)
|
|||
|
||||
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()
|
||||
|
@ -105,23 +122,6 @@ class ProjectViewSet(LikedResourceMixin, HistoryResourceMixin, ModelCrudViewSet)
|
|||
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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -9,7 +9,8 @@
|
|||
"kanban_order",
|
||||
"taskboard_order",
|
||||
"us_order",
|
||||
"custom_attributes"
|
||||
"custom_attributes",
|
||||
"tribe_gig",
|
||||
] %}
|
||||
|
||||
{% for field_name, values in changed_fields.items() %}
|
||||
|
|
|
@ -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 %}
|
||||
|
|
|
@ -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),
|
||||
),
|
||||
]
|
|
@ -21,6 +21,7 @@ from django.utils.translation import ugettext_lazy as _
|
|||
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
|
||||
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
@ -45,7 +46,8 @@ class RolePointsField(serializers.WritableField):
|
|||
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)
|
||||
|
@ -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
|
||||
|
|
|
@ -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"]
|
||||
|
|
Loading…
Reference in New Issue