Django Rest Framework Serializer PrimaryKeyRelatedField pass in uuid list
Итак, я пытаюсь сделать приложение для социальных сетей, и пользователи могут отмечать других пользователей в своих сообщениях.
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']
Для сериализации uuids для упомянутых_пользователей я следовал этим инструкциям. Все работает хорошо, я могу отправить один uuid правильно следующим образом:
Но когда я пытаюсь отправить более одного uuids, я получаю эту ошибку:
Вот мой сериализатор:
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',
]
Что я делаю неправильно? Каков правильный способ отправки списка uuids? Также, является ли данный метод, который я использую, эффективным, любая помощь будет оценена по достоинству. Спасибо.
Кроме того, я пробовал добавлять двойные кавычки для uuids, а также пытался использовать квадратные скобки '[]', но это не решило мою проблему.
PS - Когда я отправляю данные в этот API из мобильного приложения, как я буду отправлять их, это будет тот же способ, что и здесь, или другой?
После попытки использовать ListField(), сериализатор drf, и его ошибка не может быть пустым списком, я вдохновился TagListSerializer() из django-taggit, и сделал свой собственный пользовательский сериализатор, я могу загружать строки, даже пустой список, что в основном означает, что я не хочу никого помечать. Однако, я должен проверить, является ли строка действительным uuid.
Вот код для сериализатора
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
Надеюсь, это поможет кому-нибудь, кто пытается передать список строк в сериализатор, где список может быть и пустым.