I am working on a POST request where first a Tag is saved and then a Tagging - these are text labels relating to a picture (Resource).
These are the two serializers:
class TagSerializer(serializers.ModelSerializer):
class Meta:
model = Tag
fields = ('name', 'language')
def create(self, 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
This is the post request in the view:
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)
I have tested the serializers by getting objects in the browser. This is what a Tag object looks like in the browser:
{ "name": "yellow", "language": "en" }
this is the Tagging object:
{ "id": 27718, "user_id": 26213, "gameround_id": 27, "resource_id": 7, "tag": { "id": 461345, "name": "sphere", "language": "en" }, "created": "2020-10-28T23:43:40.544000Z", "score": 0, "origin": "" }
The POST request for a Tagging object only works if I give it an id of a Tag, I cannot work with a nested Tag as I am trying to in the Post method. What I tried out is the line that I have commented out in the TaggingSerializer.
What I also don't understand is:
Why does the Tag object have an id when it is nested inside the Tagging object, even though I have removed the field 'id' from the TagSerializer?
How can I make my post request work?
Please help, I have tried everything out that I could think of and find online so far.
