Задать вопрос
LexxXell
@LexxXell
Программист и немного IT-журналист

Как в сериалайзере подменить значение полей на значения из родителя?

Есть модель:
class Clip(models.Model):
    parent = models.ForeignKey('self', on_delete=models.CASCADE, null=True, blank=True)
    name = models.CharField("Clip name", max_length=150)
    video_file = models.FileField("Clip", upload_to="clips", null=True)
    thumbnail = models.ImageField("Thumbnail", upload_to="thumbnails/", null=True)
    youtube_link = models.URLField("Link to clip on YouTube", blank=True)

есть сериализатор:
class ClipSerializer(serializers.ModelSerializer):
    class Meta:
        model = Clip
        exclude = [
            "video_file",
        ]


Необходимо, если поле родителя is not None подменять значения всех полей ребенка значениями соответствующих полей родителя при сериализации.
  • Вопрос задан
  • 543 просмотра
Подписаться 1 Простой Комментировать
Решения вопроса 1
LexxXell
@LexxXell Автор вопроса
Программист и немного IT-журналист
Нашел решение
Дописываем проперти в модель:
class Clip(models.Model):
    parent = models.ForeignKey('self', on_delete=models.CASCADE, null=True, blank=True)
    name = models.CharField("Clip name", max_length=150)
    video_file = models.FileField("Clip", upload_to="clips", null=True)
    thumbnail = models.ImageField("Thumbnail", upload_to="thumbnails/", null=True)
    youtube_link = models.URLField("Link to clip on YouTube", blank=True)

    @property
    def get_name(self):
        if self.parent is not None:
            return Clip.objects.get(id=self.parent.id).name
        return self.name

    @property
    def get_artist(self):
        if self.parent is not None:
            return Clip.objects.get(id=self.parent.id).artist
        return self.artist

    @property
    def get_thumbnail(self):
        if self.parent is not None:
            return Clip.objects.get(id=self.parent.id).thumbnail.name
        return self.thumbnail.name

    @property
    def get_youtube_link(self):
        if self.parent is not None:
            return Clip.objects.get(id=self.parent.id).youtube_link
        return self.youtube_link


а в сериализаторе обращаеся к ним по serializers.ReadOnlyField
class ClipSerializer(serializers.ModelSerializer):

    name = serializers.ReadOnlyField(source="get_name")
    artist = serializers.ReadOnlyField(source="get_artist")
    thumbnail = serializers.ReadOnlyField(source="get_thumbnail")
    youtube_link = serializers.ReadOnlyField(source="get_youtube_link")

    class Meta:
        model = Clip
        exclude = [
            "video_file",
        ]


Важно учитывать, что теперь это сериализатор преимущественно для GET запросов. Для POST и PUT запросов стоит создать копию исходного сериализатора и использовать его.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы