class ProjectDetailSerializer(ProjectSerializer): us_statuses = UserStoryStatusSerializer(many=True, required=False) # User Stories points = PointsSerializer(many=True, required=False) task_statuses = TaskStatusSerializer(many=True, required=False) # Tasks issue_statuses = IssueStatusSerializer(many=True, required=False) issue_types = IssueTypeSerializer(many=True, required=False) priorities = PrioritySerializer(many=True, required=False) # Issues severities = SeveritySerializer(many=True, required=False) userstory_custom_attributes = UserStoryCustomAttributeSerializer( source="userstorycustomattributes", many=True, required=False) task_custom_attributes = TaskCustomAttributeSerializer( source="taskcustomattributes", many=True, required=False) issue_custom_attributes = IssueCustomAttributeSerializer( source="issuecustomattributes", many=True, required=False) roles = ProjectRoleSerializer(source="roles", many=True, read_only=True) members = serializers.SerializerMethodField(method_name="get_members") total_memberships = serializers.SerializerMethodField( method_name="get_total_memberships") def get_members(self, obj): qs = obj.memberships.filter(user__isnull=False) qs = qs.extra( select={"complete_user_name": "concat(full_name, username)"}) qs = qs.order_by("complete_user_name") qs = qs.select_related("role", "user") serializer = ProjectMemberSerializer(qs, many=True) return serializer.data def get_total_memberships(self, obj): return services.get_total_project_memberships(obj)
class IssueSerializer(WatchersValidator, VoteResourceSerializerMixin, EditableWatchedResourceModelSerializer, serializers.ModelSerializer): tags = TagsField(required=False) external_reference = PgArrayField(required=False) is_closed = serializers.Field(source="is_closed") comment = serializers.SerializerMethodField("get_comment") generated_user_stories = serializers.SerializerMethodField("get_generated_user_stories") blocked_note_html = serializers.SerializerMethodField("get_blocked_note_html") description_html = serializers.SerializerMethodField("get_description_html") status_extra_info = BasicIssueStatusSerializer(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) class Meta: model = models.Issue read_only_fields = ('id', 'ref', 'created_date', 'modified_date') def get_comment(self, obj): # NOTE: This method and field is necessary to historical comments work return "" def get_generated_user_stories(self, obj): return [{ "id": us.id, "ref": us.ref, "subject": us.subject, } for us in obj.generated_user_stories.all()] def get_blocked_note_html(self, obj): return mdrender(obj.project, obj.blocked_note) def get_description_html(self, obj): return mdrender(obj.project, obj.description)
class UserAdminSerializer(UserSerializer): total_private_projects = serializers.SerializerMethodField( "get_total_private_projects") total_public_projects = serializers.SerializerMethodField( "get_total_public_projects") class Meta: model = User # IMPORTANT: Maintain the UserSerializer Meta up to date # with this info (including here the email) fields = ("id", "username", "full_name", "full_name_display", "email", "color", "bio", "lang", "theme", "timezone", "is_active", "photo", "big_photo", "gravatar_url", "max_private_projects", "max_public_projects", "max_memberships_private_projects", "max_memberships_public_projects", "total_private_projects", "total_public_projects") read_only_fields = ("id", "email", "max_private_projects", "max_public_projects", "max_memberships_private_projects", "max_memberships_public_projects") def get_total_private_projects(self, user): return user.owned_projects.filter(is_private=True).count() def get_total_public_projects(self, user): return user.owned_projects.filter(is_private=False).count()
class IssueSerializer(WatchersValidator, serializers.ModelSerializer): tags = TagsField(required=False) external_reference = PgArrayField(required=False) is_closed = serializers.Field(source="is_closed") comment = serializers.SerializerMethodField("get_comment") generated_user_stories = serializers.SerializerMethodField("get_generated_user_stories") blocked_note_html = serializers.SerializerMethodField("get_blocked_note_html") description_html = serializers.SerializerMethodField("get_description_html") votes = serializers.SerializerMethodField("get_votes_number") class Meta: model = models.Issue read_only_fields = ('id', 'ref', 'created_date', 'modified_date') def get_comment(self, obj): # NOTE: This method and field is necessary to historical comments work return "" def get_generated_user_stories(self, obj): return obj.generated_user_stories.values("id", "ref", "subject") def get_blocked_note_html(self, obj): return mdrender(obj.project, obj.blocked_note) def get_description_html(self, obj): return mdrender(obj.project, obj.description) def get_votes_number(self, obj): # The "votes_count" attribute is attached in the get_queryset of the viewset. return getattr(obj, "votes_count", 0)
class MilestoneSerializer(WatchersValidator, WatchedResourceModelSerializer, serializers.ModelSerializer): user_stories = UserStoryListSerializer(many=True, required=False, read_only=True) total_points = serializers.SerializerMethodField("get_total_points") closed_points = serializers.SerializerMethodField("get_closed_points") class Meta: model = models.Milestone read_only_fields = ("id", "created_date", "modified_date") def get_total_points(self, obj): return sum(obj.total_points.values()) def get_closed_points(self, obj): return sum(obj.closed_points.values()) def validate_name(self, attrs, source): """ Check the milestone name is not duplicated in the project on creation """ qs = None # If the milestone exists: if self.object and attrs.get("name", None): qs = models.Milestone.objects.filter(project=self.object.project, name=attrs[source]).exclude(pk=self.object.pk) if not self.object and attrs.get("project", None) and attrs.get("name", None): qs = models.Milestone.objects.filter(project=attrs["project"], name=attrs[source]) if qs and qs.exists(): raise serializers.ValidationError(_("Name duplicated for the project")) return attrs
class TaskSerializer(WatchersValidator, serializers.ModelSerializer): tags = TagsField(required=False, default=[]) external_reference = PgArrayField(required=False) comment = serializers.SerializerMethodField("get_comment") milestone_slug = serializers.SerializerMethodField("get_milestone_slug") blocked_note_html = serializers.SerializerMethodField( "get_blocked_note_html") description_html = serializers.SerializerMethodField( "get_description_html") is_closed = serializers.SerializerMethodField("get_is_closed") class Meta: model = models.Task read_only_fields = ('id', 'ref', 'created_date', 'modified_date') def get_comment(self, obj): return "" def get_milestone_slug(self, obj): if obj.milestone: return obj.milestone.slug else: return None def get_blocked_note_html(self, obj): return mdrender(obj.project, obj.blocked_note) def get_description_html(self, obj): return mdrender(obj.project, obj.description) def get_is_closed(self, obj): return obj.status.is_closed
class ProjectDetailSerializer(ProjectSerializer): roles = serializers.SerializerMethodField("get_roles") memberships = serializers.SerializerMethodField("get_memberships") us_statuses = UserStoryStatusSerializer(many=True, required=False) # User Stories points = PointsSerializer(many=True, required=False) task_statuses = TaskStatusSerializer(many=True, required=False) # Tasks issue_statuses = IssueStatusSerializer(many=True, required=False) issue_types = IssueTypeSerializer(many=True, required=False) priorities = PrioritySerializer(many=True, required=False) # Issues severities = SeveritySerializer(many=True, required=False) userstory_custom_attributes = UserStoryCustomAttributeSerializer( source="userstorycustomattributes", many=True, required=False) task_custom_attributes = TaskCustomAttributeSerializer( source="taskcustomattributes", many=True, required=False) issue_custom_attributes = IssueCustomAttributeSerializer( source="issuecustomattributes", many=True, required=False) def get_memberships(self, obj): qs = obj.memberships.filter(user__isnull=False) qs = qs.order_by('user__full_name', 'user__username') qs = qs.select_related("role", "user") serializer = ProjectMembershipSerializer(qs, many=True) return serializer.data def get_roles(self, obj): serializer = ProjectRoleSerializer(obj.roles.all(), many=True) return serializer.data
class TaskSerializer(WatchersValidator, VoteResourceSerializerMixin, EditableWatchedResourceModelSerializer, serializers.ModelSerializer): tags = TagsAndTagsColorsField(default=[], required=False) external_reference = PgArrayField(required=False) comment = serializers.SerializerMethodField("get_comment") milestone_slug = serializers.SerializerMethodField("get_milestone_slug") blocked_note_html = serializers.SerializerMethodField("get_blocked_note_html") description_html = serializers.SerializerMethodField("get_description_html") is_closed = serializers.SerializerMethodField("get_is_closed") status_extra_info = BasicTaskStatusSerializerSerializer(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) class Meta: model = models.Task read_only_fields = ('id', 'ref', 'created_date', 'modified_date', 'owner') def get_comment(self, obj): return "" def get_milestone_slug(self, obj): if obj.milestone: return obj.milestone.slug else: return None def get_blocked_note_html(self, obj): return mdrender(obj.project, obj.blocked_note) def get_description_html(self, obj): return mdrender(obj.project, obj.description) def get_is_closed(self, obj): return obj.status is not None and obj.status.is_closed
class ProjectSerializer(FanResourceSerializerMixin, WatchedResourceModelSerializer, serializers.ModelSerializer): tags = TagsField(default=[], required=False) anon_permissions = PgArrayField(required=False) public_permissions = PgArrayField(required=False) my_permissions = serializers.SerializerMethodField("get_my_permissions") i_am_owner = serializers.SerializerMethodField("get_i_am_owner") tags_colors = TagsColorsField(required=False) total_closed_milestones = serializers.SerializerMethodField( "get_total_closed_milestones") notify_level = serializers.SerializerMethodField("get_notify_level") class Meta: model = models.Project read_only_fields = ("created_date", "modified_date", "owner", "slug") exclude = ("last_us_ref", "last_task_ref", "last_issue_ref", "issues_csv_uuid", "tasks_csv_uuid", "userstories_csv_uuid") def get_my_permissions(self, obj): if "request" in self.context: return get_user_project_permissions(self.context["request"].user, obj) return [] def get_i_am_owner(self, obj): if "request" in self.context: return is_project_owner(self.context["request"].user, obj) return False def get_total_closed_milestones(self, obj): return obj.milestones.filter(closed=True).count() def get_notify_level(self, obj): return getattr(obj, "notify_level", None)
class UserSerializer(serializers.ModelSerializer): full_name_display = serializers.SerializerMethodField("get_full_name_display") photo = serializers.SerializerMethodField("get_photo") big_photo = serializers.SerializerMethodField("get_big_photo") roles = serializers.SerializerMethodField("get_roles") projects_with_me = serializers.SerializerMethodField("get_projects_with_me") class Meta: model = User # IMPORTANT: Maintain the UserAdminSerializer Meta up to date # with this info (including there the email) fields = ("id", "username", "full_name", "full_name_display", "color", "bio", "lang", "theme", "timezone", "is_active", "photo", "big_photo", "roles", "projects_with_me") read_only_fields = ("id",) def validate_username(self, attrs, source): value = attrs[source] validator = validators.RegexValidator(re.compile('^[\w.-]+$'), _("invalid username"), _("invalid")) try: validator(value) except ValidationError: raise serializers.ValidationError(_("Required. 255 characters or fewer. Letters, " "numbers and /./-/_ characters'")) if (self.object and self.object.username != value and User.objects.filter(username=value).exists()): raise serializers.ValidationError(_("Invalid username. Try with a different one.")) return attrs def get_full_name_display(self, obj): return obj.get_full_name() if obj else "" def get_photo(self, user): return get_photo_or_gravatar_url(user) def get_big_photo(self, user): return get_big_photo_or_gravatar_url(user) def get_roles(self, user): return user.memberships. order_by("role__name").values_list("role__name", flat=True).distinct() def get_projects_with_me(self, user): request = self.context.get("request", None) requesting_user = request and request.user or None if not requesting_user or not requesting_user.is_authenticated(): return [] else: project_ids = requesting_user.memberships.values_list("project__id", flat=True) memberships = user.memberships.filter(project__id__in=project_ids) project_ids = memberships.values_list("project__id", flat=True) projects = Project.objects.filter(id__in=project_ids) return ContactProjectDetailSerializer(projects, many=True).data
class UserSerializer(serializers.Serializer): id = serializers.SerializerMethodField("get_pk") name = serializers.SerializerMethodField("get_name") def get_pk(self, obj): return obj.pk def get_name(self, obj): return obj.full_name
class FanResourceSerializerMixin(serializers.ModelSerializer): is_fan = serializers.SerializerMethodField("get_is_fan") total_fans = serializers.SerializerMethodField("get_total_fans") def get_is_fan(self, obj): # The "is_fan" attribute is attached in the get_queryset of the viewset. return getattr(obj, "is_fan", False) or False def get_total_fans(self, obj): # The "total_fans" attribute is attached in the get_queryset of the viewset. return getattr(obj, "total_fans", 0) or 0
class VoteResourceSerializerMixin(serializers.ModelSerializer): is_voter = serializers.SerializerMethodField("get_is_voter") total_voters = serializers.SerializerMethodField("get_total_voters") def get_is_voter(self, obj): # The "is_voted" attribute is attached in the get_queryset of the viewset. return getattr(obj, "is_voter", False) or False def get_total_voters(self, obj): # The "total_likes" attribute is attached in the get_queryset of the viewset. return getattr(obj, "total_voters", 0) or 0
class AttachmentSerializer(serializers.ModelSerializer): url = serializers.SerializerMethodField("get_url") thumbnail_card_url = serializers.SerializerMethodField( "get_thumbnail_card_url") attached_file = serializers.FileField(required=True) is_video = serializers.SerializerMethodField("get_is_video") markers = serializers.SerializerMethodField("get_markers") class Meta: model = models.Attachment fields = ("id", "project", "owner", "name", "attached_file", "size", "url", "thumbnail_card_url", "description", "is_deprecated", "created_date", "modified_date", "object_id", "order", "sha1", "is_video", "markers") read_only_fields = ( "owner", "created_date", "modified_date", "sha1", ) def get_url(self, obj): return obj.attached_file.url def get_thumbnail_card_url(self, obj): return services.get_card_image_thumbnailer_url(obj) def get_is_video(self, obj): if '.mp4' in obj.attached_file.url: return True else: return False def get_sources(self, obj): if self.get_is_video(obj): sources = dict(src=obj.attached_file.url, type='video/mp4') return dict(sources=[ sources, ]) return False def get_markers(self, obj): if self.get_is_video(obj): qs = obj.markers.all() from productships.serializers import MarkerSerializer qs = MarkerSerializer(qs, many=True) return qs.data # return [ # {'time': 9.5, 'text': "this"}, # {'time': 16, 'text': "is"}, # {'time': 23.6, 'text': "so"}, # {'time': 28, 'text': "cool"} # ] return []
class WikiPageSerializer(WatchersValidator, WatchedResourceModelSerializer, serializers.ModelSerializer): html = serializers.SerializerMethodField("get_html") editions = serializers.SerializerMethodField("get_editions") class Meta: model = models.WikiPage read_only_fields = ('modified_date', 'created_date') def get_html(self, obj): return mdrender(obj.project, obj.content) def get_editions(self, obj): return history_service.get_history_queryset_by_model_instance(obj).count() + 1 # +1 for creation
class SeveritySerializer(serializers.Serializer): id = serializers.SerializerMethodField("get_pk") name = serializers.SerializerMethodField("get_name") color = serializers.SerializerMethodField("get_color") def get_pk(self, obj): return obj.pk def get_name(self, obj): return obj.name def get_color(self, obj): return obj.color
class RolePointsSerializer(serializers.Serializer): role = serializers.SerializerMethodField("get_role") name = serializers.SerializerMethodField("get_name") value = serializers.SerializerMethodField("get_value") def get_role(self, obj): return obj.role.name def get_name(self, obj): return obj.points.name def get_value(self, obj): return obj.points.value
class UserProjectSettingsSerializer(serializers.ModelSerializer): project_name = serializers.SerializerMethodField("get_project_name") allowed_sections = serializers.SerializerMethodField("get_allowed_sections") class Meta: model = models.UserProjectSettings fields = ('id', 'project', 'project_name', 'homepage', 'allowed_sections') def get_project_name(self, obj): return obj.project.name def get_allowed_sections(self, obj): return get_allowed_sections(obj)
class PointSerializer(serializers.Serializer): id = serializers.SerializerMethodField("get_pk") name = serializers.SerializerMethodField("get_name") value = serializers.SerializerMethodField("get_value") def get_pk(self, obj): return obj.pk def get_name(self, obj): return obj.name def get_value(self, obj): return obj.value
class MilestoneSerializer(WatchersValidator, WatchedResourceModelSerializer, ValidateDuplicatedNameInProjectMixin): total_points = serializers.SerializerMethodField("get_total_points") closed_points = serializers.SerializerMethodField("get_closed_points") class Meta: model = models.Milestone read_only_fields = ("id", "created_date", "modified_date") def get_total_points(self, obj): return sum(obj.total_points.values()) def get_closed_points(self, obj): return sum(obj.closed_points.values())
class WatchedResourceModelSerializer(serializers.ModelSerializer): is_watcher = serializers.SerializerMethodField("get_is_watcher") total_watchers = serializers.SerializerMethodField("get_total_watchers") def get_is_watcher(self, obj): if "request" in self.context: user = self.context["request"].user return user.is_authenticated() and user.is_watcher(obj) return False def get_total_watchers(self, obj): # The "total_watchers" attribute is attached in the get_queryset of the viewset. return getattr(obj, "total_watchers", 0) or 0
class ProjectDetailAdminSerializer(ProjectDetailSerializer): is_private_extra_info = serializers.SerializerMethodField(method_name="get_is_private_extra_info") max_memberships = serializers.SerializerMethodField(method_name="get_max_memberships") class Meta: model = models.Project read_only_fields = ("created_date", "modified_date", "slug", "blocked_code") exclude = ("logo", "last_us_ref", "last_task_ref", "last_issue_ref") def get_is_private_extra_info(self, obj): return services.check_if_project_privacity_can_be_changed(obj) def get_max_memberships(self, obj): return services.get_max_memberships_for_project(obj)
class ProjectSerializer(serializers.ModelSerializer): tags = PgArrayField(required=False) anon_permissions = PgArrayField(required=False) public_permissions = PgArrayField(required=False) stars = serializers.SerializerMethodField("get_stars_number") my_permissions = serializers.SerializerMethodField("get_my_permissions") i_am_owner = serializers.SerializerMethodField("get_i_am_owner") tags_colors = TagsColorsField(required=False) users = serializers.SerializerMethodField("get_users") total_closed_milestones = serializers.SerializerMethodField( "get_total_closed_milestones") class Meta: model = models.Project read_only_fields = ("created_date", "modified_date", "owner") exclude = ("last_us_ref", "last_task_ref", "last_issue_ref", "issues_csv_uuid", "tasks_csv_uuid", "userstories_csv_uuid") def get_stars_number(self, obj): # The "stars_count" attribute is attached in the get_queryset of the viewset. return getattr(obj, "stars_count", 0) def get_my_permissions(self, obj): if "request" in self.context: return get_user_project_permissions(self.context["request"].user, obj) return [] def get_i_am_owner(self, obj): if "request" in self.context: return is_project_owner(self.context["request"].user, obj) return False def get_users(self, obj): return UserSerializer(obj.members.all(), many=True).data def get_total_closed_milestones(self, obj): return obj.milestones.filter(closed=True).count() def validate_total_milestones(self, attrs, source): """ Check that total_milestones is not null, it's an optional parameter but not nullable in the model. """ value = attrs[source] if value is None: raise serializers.ValidationError( _("Total milestones must be major or equal to zero")) return attrs
class HistoryEntrySerializer(serializers.ModelSerializer): diff = JsonField() snapshot = JsonField() values = I18NJsonField(i18n_fields=HISTORY_ENTRY_I18N_FIELDS) values_diff = I18NJsonField(i18n_fields=HISTORY_ENTRY_I18N_FIELDS) user = serializers.SerializerMethodField("get_user") delete_comment_user = JsonField() comment_versions = JsonField() class Meta: model = models.HistoryEntry exclude = ("comment_versions", ) def get_user(self, entry): user = { "pk": None, "username": None, "name": None, "photo": None, "is_active": False } user.update(entry.user) user["photo"] = get_photo_or_gravatar_url(entry.owner) if entry.owner: user["is_active"] = entry.owner.is_active if entry.owner.is_active or entry.owner.is_system: user["name"] = entry.owner.get_full_name() user["username"] = entry.owner.username return user
class TaskSerializer(CustomAttributesValuesWebhookSerializerMixin, serializers.LightSerializer): id = Field() ref = Field() created_date = Field() modified_date = Field() finished_date = Field() due_date = Field() due_date_reason = Field() subject = Field() us_order = Field() taskboard_order = Field() is_iocaine = Field() external_reference = Field() watchers = MethodField() is_blocked = Field() blocked_note = Field() description = Field() tags = Field() permalink = serializers.SerializerMethodField("get_permalink") project = ProjectSerializer() owner = UserSerializer() assigned_to = UserSerializer() status = TaskStatusSerializer() user_story = UserStorySerializer() milestone = MilestoneSerializer() def get_permalink(self, obj): return resolve_front_url("task", obj.project.slug, obj.ref) def custom_attributes_queryset(self, project): return project.taskcustomattributes.all() def get_watchers(self, obj): return list(obj.get_watchers().values_list("id", flat=True))
class EpicSerializer(CustomAttributesValuesWebhookSerializerMixin, serializers.LightSerializer): id = Field() ref = Field() created_date = Field() modified_date = Field() subject = Field() watchers = MethodField() description = Field() tags = Field() permalink = serializers.SerializerMethodField("get_permalink") project = ProjectSerializer() owner = UserSerializer() assigned_to = UserSerializer() status = EpicStatusSerializer() epics_order = Field() color = Field() client_requirement = Field() team_requirement = Field() client_requirement = Field() team_requirement = Field() def get_permalink(self, obj): return resolve_front_url("epic", obj.project.slug, obj.ref) def custom_attributes_queryset(self, project): return project.epiccustomattributes.all() def get_watchers(self, obj): return list(obj.get_watchers().values_list("id", flat=True))
class TimelineSerializer(serializers.ModelSerializer): data = serializers.SerializerMethodField("get_data") class Meta: model = models.Timeline def get_data(self, obj): #Updates the data user info saved if the user exists if hasattr(obj, "_prefetched_user"): user = obj._prefetched_user else: User = apps.get_model("users", "User") userData = obj.data.get("user", None) try: user = User.objects.get(id=userData["id"]) except User.DoesNotExist: user = None if user is not None: obj.data["user"] = { "id": user.pk, "name": user.get_full_name(), "photo": get_photo_or_gravatar_url(user), "big_photo": get_big_photo_or_gravatar_url(user), "username": user.username, "is_profile_visible": user.is_active and not user.is_system, "date_joined": user.date_joined } return obj.data
class CustomAttributesValuesExportSerializerMixin(serializers.ModelSerializer): custom_attributes_values = serializers.SerializerMethodField( "get_custom_attributes_values") def custom_attributes_queryset(self, project): raise NotImplementedError() def get_custom_attributes_values(self, obj): def _use_name_instead_id_as_key_in_custom_attributes_values( custom_attributes, values): ret = {} for attr in custom_attributes: value = values.get(str(attr["id"]), None) if value is not None: ret[attr["name"]] = value return ret try: values = obj.custom_attributes_values.attributes_values custom_attributes = self.custom_attributes_queryset( obj.project).values('id', 'name') return _use_name_instead_id_as_key_in_custom_attributes_values( custom_attributes, values) except ObjectDoesNotExist: return None
class IssueSerializer(CustomAttributesValuesWebhookSerializerMixin, serializers.LightSerializer): id = Field() ref = Field() created_date = Field() modified_date = Field() finished_date = Field() due_date = Field() due_date_reason = Field() subject = Field() external_reference = Field() watchers = MethodField() description = Field() tags = Field() permalink = serializers.SerializerMethodField("get_permalink") project = ProjectSerializer() milestone = MilestoneSerializer() owner = UserSerializer() assigned_to = UserSerializer() status = IssueStatusSerializer() type = IssueTypeSerializer() priority = PrioritySerializer() severity = SeveritySerializer() time_spent_note = Field() affects_customer = Field() def get_permalink(self, obj): return resolve_front_url("issue", obj.project.slug, obj.ref) def custom_attributes_queryset(self, project): return project.issuecustomattributes.all() def get_watchers(self, obj): return list(obj.get_watchers().values_list("id", flat=True))
class AttachmentExportSerializerMixin(serializers.ModelSerializer): attachments = serializers.SerializerMethodField("get_attachments") def get_attachments(self, obj): content_type = ContentType.objects.get_for_model(obj.__class__) attachments_qs = attachments_models.Attachment.objects.filter( object_id=obj.pk, content_type=content_type) return AttachmentExportSerializer(attachments_qs, many=True).data