Добавить дополнительные поля в сериализаторе из моделей отношений один к одному - PullRequest
2 голосов
/ 22 июня 2019

В этом проекте у меня есть две модели ученика и родителя, связанные друг с другом через одно-одно поле.

В родительском сериализаторе я хочу добавить атрибуты учеников, такие как возраст. Я думаю об использовании SerializerMethodField для обоих случаев, есть ли лучший способ сделать это?

Я не получаю запросов о том, как получить атрибуты объекта, и небольшое объяснение было бы здорово.

Вот что я сделал до сих пор.

Models.py

class Student(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True, default=None)
    batch = models.ForeignKey(Batch, on_delete=models.CASCADE, null=True, related_name='students')
    email = models.EmailField(null=True)
    phone_number = models.CharField(max_length=10, null=True)
    dob = models.DateField(blank=True, null=True, help_text="Enter in the following format : YYYY-MM-DD")
    address = models.TextField(max_length=150, null=True)
    age = models.IntegerField(blank=True)
    image = models.ImageField(upload_to='profile_pictures', default='student_image.png', blank=True)

    @property
    def remarks(self):
        return self.remark_set.all()

    @property
    def marks(self):
        return self.marks_set.all()

    def __str__(self):
        return self.user.firstName + ' ' + self.user.lastName

class Parent(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True, default=None)
    child = models.ForeignKey(Student, on_delete=models.CASCADE)
    email = models.EmailField(null=True)
    phone_number = models.CharField(max_length=10, null=True)
    address = models.TextField(max_length=150, null=True)
    image = models.ImageField(upload_to='profile_pictures', default='student_image.png', blank=True)

    def __str__(self):
        return self.user.firstName + ' ' + self.user.lastName


Serilaizer.py

class ParentSerializer(serializers.HyperlinkedModelSerializer):
    student_age = serializers.SerializerMethodField()
    student_batch = serializers.SerializerMethodField()
    parent_name = serializers.SerializerMethodField()

    class Meta:
        model = Parent
        fields = "__all__"

    def get_student_age(self, obj):
        return Parent.objects.get(child__age = self.obj.user.child)

    def get_student_batch(self, obj):
        return Parent.objects.get(child__bacth = self.obj.user.child)

    def get_parent_name(self, user):
        return Parent.objects.get(user=self.request.user)


Views.py

class ParentView( mixins.ListModelMixin, mixins.RetrieveModelMixin,viewsets.GenericViewSet):
    queryset = Parent.objects.all()
    serializer_class = serializers.ParentSerializer

1 Ответ

1 голос
/ 22 июня 2019

первый путь:

from apps.models import Student, parent

class BasicUserSerializer(serializers.ModelSerializer):
    class Meta:
       model =  User
       fields = "__all__"


class BasicStudentSerializer(serializers.ModelSerializer):
    class Meta:
       model =  Student
       fields = "__all__"


class ParentSerializer(serializers.ModelSerializer):
    user = BasicUserSerializer(read_only=True,many=False)
    child = BasicStudentSerializer(read_only=True, many=True)

    class Meta:
        model = Parent
        fields = '__all__'

вы можете сделать это так. его замените поле сериализатора, которое вы хотите, и если у родителя есть несколько дочерних, то в дочернем поле у ​​вас есть новая вся дочерняя информация в виде словаря.

=============================================== =================

Второй способ использования HyperLinkModel .

class ParentSerializer(serializers.ModelSerializer):
    user = serializers.HyperlinkedRelatedField(read_only=True,many=False)
    child = serializers.HyperlinkedRelatedField(read_only=True, many=True)

    class Meta:
        model = Parent
        fields = '__all__'

но обратите внимание, что сначала у вас будет независимый класс сериализатора, который каждый раз, когда вам нужно сериализовать класс модели, связанный с User или Child, вы можете использовать их просто.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...