Сериализаторы для связанных моделей. Задание 2

Добавьте к постам хештеги. Хештеги должны храниться в отдельной таблице в БД и быть связаны с постами отношением «многие-ко-многим».

При запросе постов должна возвращаться информация о всех связанных с конкретным постом хештегах, а при добавлении или обновлении поста нужно обеспечить возможность передавать названия хештегов списком прямо в теле запроса. Без указания хештегов пост через API тоже должен создаваться.

Пример POST-запроса для создания поста с хештегами:

{
    "text": "Текст для моего поста",
    "author": 1,
    "tag": [
        {"name": "хобби"},
        {"name": "личное"}
        ]
} 

Подсказка:
Опишите сериализатор для модели Tag.

Опишите метод create() для сериализатора PostSerializer:

  • если поля tag нет в запросе — нужно создать пост из тех данных, которые были переданы;
  • если поле tag есть в запросе — нужно создать пост из переданных данных (без учёта поля tag), добавить новые теги из переданного списка тегов в БД (если их там ещё нет), добавить в таблицу TagPost записи, которые свяжут новый пост с теми тегами, которые пришли в запросе или уже присутствуют в БД.

Код serializers.py:

from rest_framework import serializers

from .models import Group, Post, Tag, TagPost

# опишите сериализатор для хештегов
class TagSerializer(serializers.ModelSerializer):
    class Meta:
        fields = ('name', )
        model = Tag
    

class PostSerializer(serializers.ModelSerializer):
    group = serializers.SlugRelatedField(slug_field='slug', queryset=Group.objects.all(), required=False)
    tag = TagSerializer(required=False, many=True)

    class Meta:
        fields = ('id', 'text', 'author', 'image', 'pub_date', 'group', 'tag')
        model = Post

    def create(self, validated_data):
        if 'tag' not in self.initial_data:
            #tags=validated_data.pop('tag')
            post=Post.objects.create(**validated_data)
            return post
        else:
            tag=validated_data.pop('tag')
            post=Post.objects.create(**validated_data)
            
            for one_tag in tag:
                current_tag, status = Tag.objects.get_or_create(**one_tag)
                TagPost.objects.create(tag=current_tag, post=post)
            return post




Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: