Skip to content

Commit

Permalink
feat: add extra fields options to relationships
Browse files Browse the repository at this point in the history
This change is applied to course-experience api.
The relations file inherit from json api relation but add the
possibility to add some extra fields using a function.
The function has to be passed through the new relation using `get_extra_fields` kwarg.
There you can calculate a dict that would be added to corresponding relationhips field.
The base json api only add id and type, with this change you cad add extra model
attributes.
https://github.com/django-json-api/django-rest-framework-json-api/blob/main/rest_framework_json_api/relations.py#L255

chore: pr suggestions

Co-authored-by: Andrey Cañon <[email protected]>
  • Loading branch information
johanseto and andrey-canon committed Jul 7, 2023
1 parent 034ba4f commit a345957
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 0 deletions.
40 changes: 40 additions & 0 deletions eox_nelp/course_experience/api/v1/relations.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
"""Relations used for customize experience views. The relations are used to specify how to manage
the relations fields in the serializers.
https://github.com/encode/django-rest-framework/blob/master/rest_framework/relations.py
"""
from rest_framework_json_api.relations import ResourceRelatedField


class ExperienceResourceRelatedField(ResourceRelatedField):
"""Class to configure relations for course experience API.
Ancestors:
relation (ResourceRelatedField): the ResourceRelatedField relation from json api
"""
def __init__(self, **kwargs):
""" Include an additional kwargs parameter to manage the extra model fields to be shown.
The value of the kwarg should be a function with kwargs accepting value: (value=instance).
get_extra_fields (function)
"""
self.get_extra_fields = kwargs.pop('get_extra_fields', None)
super().__init__(**kwargs)

def to_representation(self, value):
"""Add to the base json api representation extra fields apart from `id` and `type`
using a function passed via `self.get_extra_fields`
https://github.com/django-json-api/django-rest-framework-json-api/blob/main/rest_framework_json_api/relations.py#L255
The attributes shape is based on
https://jsonapi.org/format/#document-resource-objects
Args:
value (instance model): instance of foreign model extracted from relation
Returns:
json_api_representation (ordered-dict): json api representation with extra model data in attributes field.
"""
json_api_representation = super().to_representation(value)

if self.get_extra_fields and callable(self.get_extra_fields):
json_api_representation.update(self.get_extra_fields(value=value))

return json_api_representation
11 changes: 11 additions & 0 deletions eox_nelp/course_experience/api/v1/serializers.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
"""Serializers used for the experience views."""
from django.contrib.auth import get_user_model
from rest_framework_json_api import serializers

from eox_nelp.course_experience.api.v1.relations import ExperienceResourceRelatedField
from eox_nelp.course_experience.models import (
FeedbackCourse,
LikeDislikeCourse,
LikeDislikeUnit,
ReportCourse,
ReportUnit,
)
from eox_nelp.edxapp_wrapper.course_overviews import CourseOverview

User = get_user_model()


class ExperienceSerializer(serializers.ModelSerializer):
Expand All @@ -20,6 +25,12 @@ class ExperienceSerializer(serializers.ModelSerializer):
username = serializers.CharField(
source="author.username", required=False, allow_blank=True
)
course_id = ExperienceResourceRelatedField(
queryset=CourseOverview.objects,
)
author = ExperienceResourceRelatedField(
queryset=User.objects,
)


class LikeDislikeUnitExperienceSerializer(ExperienceSerializer):
Expand Down

0 comments on commit a345957

Please sign in to comment.