Django Rest Framework Serializer PrimaryKeyRelatedField pass in uuid list

So, I am trying to make a social media application and users can tag other users in their post.

class Post(models.Model):
author = models.ForeignKey(User, related_name='posts', on_delete=models.CASCADE)
caption = models.CharField(max_length=100, null=True, blank=True)
id = models.UUIDField(default=uuid.uuid4, unique=True, primary_key=True, editable=False)
date_created = models.DateTimeField(auto_now_add=True)
date_edited = models.DateTimeField(auto_now=True)
allow_comments = models.BooleanField(default=True)
archived = models.BooleanField(default=False)
media_file_url = models.FileField(upload_to='videos/', validators=[validate_file_extension])

tags = TaggableManager(blank=True, through=TaggedHashtag)

mentioned_users = models.ManyToManyField(User, blank=True, through='MentionedUser')


class MentionedUser(models.Model):
id = models.UUIDField(default=uuid.uuid4, unique=True, primary_key=True, editable=False)
date_created = models.DateTimeField(auto_now_add=True)

post = models.ForeignKey(Post, on_delete=models.CASCADE)
tagged_user = models.ForeignKey(User, on_delete=models.CASCADE)

class Meta:
    unique_together = (('post', 'tagged_user'))
    ordering = ['date_created']

For serializing the uuids for the mentioned_users, I followed these instructions. Everything works fine, I can submit one uuid correctly like this:

enter image description here

But when I try to submit more than one uuids, I get this error: enter image description here

Here is my serializer:

class PostSerializer(TaggitSerializer, serializers.ModelSerializer):

tags = TagListSerializerField()
mentioned_users = serializers.PrimaryKeyRelatedField(many=True, allow_null=True, queryset=User.objects.all(), pk_field=serializers.UUIDField(format='hex'))
id = serializers.CharField(read_only=True)

class Meta:
    model = Post
    fields = [
        'caption',
        'allow_comments',
        'media_file_url',
        'id',
        'tags',
        'mentioned_users',
    ]

What am I doing wrong here? What is the correct way to submit list of uuids? Also, is the present method I am using efficient, any form of help would be appreciated. Thank You.

Also, I tried adding double quotes for the uuids and also, tried to use '[]' box brackets, but it did not solve my problem.

PS - When I post data to this API from a mobile app, how will I submit it, will it be the same way here or will it be different?

After trying to use ListField(), a drf serializer, and it having its own cannot be empty list error, I took inspiration from TagListSerializer() from django-taggit, and made my own custom serializer, I can upload strings, even empty list, which basically means I don't want to tag anyone. However, I do have to check if the string is valid uuid.

Here is the code for the serializer

from rest_framework import serializer
import json
from django.utils.translation import gettext_lazy

class MentionedUsersIdSerializerField(serializers.Field):
child = serializers.CharField()
initial = []
default_error_messages = {
    "not_a_list": gettext_lazy(
        'Expected a list of items but got type "{input_type}".'
    ),
    "invalid_json": gettext_lazy(
        "Invalid json list. A tag list submitted in string"
        " form must be valid json."
    ),
    "not_a_str": gettext_lazy("All list items must be of string type."),
}
order_by = None

def __init__(self, **kwargs):
    pretty_print = kwargs.pop("pretty_print", True)

    style = kwargs.pop("style", {})
    kwargs["style"] = {"base_template": "textarea.html"}
    kwargs["style"].update(style)

    super().__init__(**kwargs)

    self.pretty_print = pretty_print

def to_internal_value(self, value):
    if isinstance(value, str):
        if not value:
            value = "[]"
        try:
            value = json.loads(value)
        except ValueError:
            self.fail("invalid_json")

    if not isinstance(value, list):
        self.fail("not_a_list", input_type=type(value).__name__)

    for s in value:
        if not isinstance(s, str):
            self.fail("not_a_str")

        self.child.run_validation(s)

    return value

def to_representation(self, value):
    if not isinstance(value, list):
        if not isinstance(value, list):
            if self.order_by:
                ids = value.all().order_by(*self.order_by)
            else:
                ids = value.all()
            value = [id.name for id in ids]
        value = list(value, pretty_print=self.pretty_print)

    return value

I hope this helps someone trying to submit a list of strings to the serializer, where the list can be empty as well.

Back to Top