From a3459577db620973f93e510ce4c33b1ea1061bfd Mon Sep 17 00:00:00 2001 From: Johan Castiblanco Date: Thu, 6 Jul 2023 14:59:13 -0500 Subject: [PATCH] feat: add extra fields options to relationships MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- .../course_experience/api/v1/relations.py | 40 +++++++++++++++++++ .../course_experience/api/v1/serializers.py | 11 +++++ 2 files changed, 51 insertions(+) create mode 100644 eox_nelp/course_experience/api/v1/relations.py diff --git a/eox_nelp/course_experience/api/v1/relations.py b/eox_nelp/course_experience/api/v1/relations.py new file mode 100644 index 00000000..c90c1918 --- /dev/null +++ b/eox_nelp/course_experience/api/v1/relations.py @@ -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 diff --git a/eox_nelp/course_experience/api/v1/serializers.py b/eox_nelp/course_experience/api/v1/serializers.py index 31b8ba69..39bf3793 100644 --- a/eox_nelp/course_experience/api/v1/serializers.py +++ b/eox_nelp/course_experience/api/v1/serializers.py @@ -1,6 +1,8 @@ """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, @@ -8,6 +10,9 @@ ReportCourse, ReportUnit, ) +from eox_nelp.edxapp_wrapper.course_overviews import CourseOverview + +User = get_user_model() class ExperienceSerializer(serializers.ModelSerializer): @@ -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):