Как получить доступ к полю внутри вложенного сериализатора и заставить работать пост-запрос?
Я работаю над POST-запросом, в котором сначала сохраняется Tag, а затем Tagging - это текстовые метки, относящиеся к картинке (ресурсу).
Вот два сериализатора:
serializers.py
class TagSerializer(serializers.ModelSerializer):
class Meta:
model = Tag
fields = ('name', 'language')
def create(self, validated_data):
tag_data = validated_data.pop('tag')
Tag.objects.create(**tag_data)
return tag_data
def to_representation(self, data):
data = super().to_representation(data)
return data
class TaggingSerializer(serializers.ModelSerializer):
tag_id = serializers.PrimaryKeyRelatedField(queryset=Tag.objects.all(),
required=False,
source='tag',
write_only=False)
# tag = TagSerializer(required=False, write_only=False).data.get('name')
resource_id = serializers.PrimaryKeyRelatedField(queryset=Resource.objects.all(),
required=True,
source='resource',
write_only=False)
gameround_id = serializers.PrimaryKeyRelatedField(queryset=Gameround.objects.all(),
required=False,
source='gameround',
write_only=False)
user_id = serializers.PrimaryKeyRelatedField(queryset=CustomUser.objects.all(),
required=False,
source='user',
write_only=False)
class Meta:
model = Tagging
fields = ('id', 'user_id', 'gameround_id', 'resource_id', 'tag_id', 'created', 'score', 'origin')
depth = 1
def create(self, validated_data):
"""Create and return a new tagging"""
tagging = Tagging(
user=validated_data.get("user"),
gameround=validated_data.get("gameround"),
resource=validated_data.get("resource"),
tag=validated_data.get("tag"),
created=datetime.now(),
score=validated_data.get("score"),
origin=validated_data.get("origin")
)
tagging.save()
return tagging
def to_representation(self, data):
data = super().to_representation(data)
return data
Это запрос на пост в представлении: views.py
def post(self, request, *args, **kwargs):
if not isinstance(request.user, CustomUser):
current_user_id = 1
else:
current_user_id = request.user.pk
gameround = request.data.get('gameround', '')
random_resource = request.data.get('resource', '')
created = datetime.now()
score = 0
origin = ''
name = request.data.get('name', '')
language = request.data.get('language', '')
tag_serializer = TagSerializer(data=request.data)
tagging_serializer = TaggingSerializer(data=request.data)
if Tag.objects.all().filter(name=name, language=language).exists():
if Tagging.objects.all().filter(user=current_user_id, gameround=gameround, resource=random_resource,
tag=Tag.objects.all().get(name=name, language=language),
created=created, score=score+5, origin=origin).exists():
if tag_serializer.is_valid(raise_exception=True):
tag = request.data
tag_serializer.save(tag)
if tagging_serializer.is_valid(raise_exception=True):
tagging_serializer.save(tagging=request.data, tag=tag)
return Response({"status": "success", "data": tagging_serializer.data},
status=status.HTTP_201_CREATED)
else:
return Response({"status": "success", "data": tag_serializer.data},
status=status.HTTP_201_CREATED)
else:
return Response({"status": "error", "data": tag_serializer.errors},
status=status.HTTP_400_BAD_REQUEST)
Я протестировал сериализаторы, получив объекты в браузере. Вот как выглядит объект Tag в браузере:
{ "имя": "желтый", "language": "en" }
это объект тегов:
{ "id": 27718, "user_id": 26213, "gameround_id": 27, "resource_id": 7, "tag": { "id": 461345, "name": "сфера", "language": "en" }, "created": "2020-10-28T23:43:40.544000Z", "score": 0, "origin": "" }
POST-запрос для объекта Tagging работает, только если я даю ему идентификатор Tag, я не могу работать со вложенным Tag, как я пытаюсь сделать в методе Post. Я попробовал использовать строку, которую я закомментировал в TaggingSerializer.
Что я также не понимаю, так это:
Почему объект Tag имеет id, когда он вложен в объект Tagging, хотя я удалил поле 'id' из TagSerializer?
Как я могу заставить работать мой пост-запрос?
Помогите пожалуйста, я перепробовал все, что мог придумать и найти в интернете до сих пор.