Я использовал django -tag git, чтобы добавить теги к моей модели. Django Версия: 2.2.10, Python Версия: 3.8.1
Сейчас я пытаюсь интегрировать теги с django rest-framework, например, CREATE / UPDATE / REMOVE экземпляры модели с / без теги.
Моя проблема: я не могу создать (через rest api) новый экземпляр моей модели с тегами. Я могу получить экземпляры модели без проблем.
Мои модели.py:
from taggit.managers import TaggableManager
class Task(models.Model):
name = models.CharField(max_length=100, blank=False)
...
tags = TaggableManager(blank=True)
def get_tags(self):
""" names() is a django-taggit method, returning a ValuesListQuerySet
(basically just an iterable) containing the name of each tag as a string
"""
return self.tags.names()
def __str__(self):
return self.title
Мои serializers.py:
class TagsField(serializers.Field):
""" custom field to serialize/deserialize TaggableManager instances.
"""
def to_representation(self, value):
""" in drf this method is called to convert a custom datatype into a primitive,
serializable datatype.
In this context, value is a plain django queryset containing a list of strings.
This queryset is obtained thanks to get_tags() method on the Task model.
Drf is able to serialize a queryset, hence we simply return it without doing nothing.
"""
return value
def to_internal_value(self, data):
""" this method is called to restore a primitive datatype into its internal
python representation.
This method should raise a serializers.ValidationError if the data is invalid.
"""
return data
class TaskSerializer(serializers.ModelSerializer):
# tags field in Task model is implemented via TaggableManager class from django-taggit.
# By default, drf is not able to serialize TaggableManager to json.
# get_tags() is a method of the Task model class, which returns a Queryset containing
# the list of tags as strings. This Queryset can be serialized without issues.
tags = TagsField(source="get_tags")
class Meta:
model = Task
fields = [
"name",
...,
"tags",
]
Всякий раз, когда я пытаюсь создать новый экземпляр моей модели Task через API-интерфейс POST я получаю следующую ошибку:
TypeError at /taskdrop/v1/task/
Got a `TypeError` when calling `Task.objects.create()`. This may be because you have a writable field on the serializer class that is not a valid argument to `Task.objects.create()`. You may need to make the field read-only, or override the TaskSerializer.create() method to handle this correctly.
Original exception was:
Traceback (most recent call last):
File "/home/daniele/prj/ea/TaskDrop/venv/lib/python3.8/site-packages/rest_framework/serializers.py", line 948, in create
instance = ModelClass._default_manager.create(**validated_data)
File "/home/daniele/prj/ea/TaskDrop/venv/lib/python3.8/site-packages/django/db/models/manager.py", line 82, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/home/daniele/prj/ea/TaskDrop/venv/lib/python3.8/site-packages/django/db/models/query.py", line 420, in create
obj = self.model(**kwargs)
File "/home/daniele/prj/ea/TaskDrop/venv/lib/python3.8/site-packages/django/db/models/base.py", line 501, in __init__
raise TypeError("%s() got an unexpected keyword argument '%s'" % (cls.__name__, kwarg))
TypeError: Task() got an unexpected keyword argument 'get_tags'
Я как бы застрял прямо сейчас ... поле определенно не только для чтения и касается переопределения TaskSerializer.create () метод, я не знаю точно, как это сделать.
Плюс, я немного запутался по поводу переопределения метода TagsField (serializers.Field) и .create (). Насколько я понимаю, если я создаю поле настраиваемого сериализатора, больше не нужно переопределять .create ().
Наконец, я попытался использовать django -tag git -serializer безуспешно: модель создается, но пропущенные теги просто отсутствуют.
Как это исправить? Спасибо.