Я використовую Django-rest-framework для побудови API. У мене є модель Chair
Я будую огляд для. Він має ManyToManyField
до моделі Tag
, тому кожен стілець має кілька тегів.
Tag
є моделлю Django, але під час взаємодії з API я не хочу бачити JSON-дикт для кожного тегу; я просто хочу використовувати ім'я тегу.
Наприклад при перегляді Chair
в API я хочу бачити, що він має таке:
{
"tags": ["meow", "frrr", "nutella"],
... Any other chair attributes
}
І так само, коли я створюю файл Chair
, Я хочу мати можливість передавати список назв тегів, а потім для кожного з них робити get_or_create
під цією назвою. (Отже, я або використовую існуючий тег із таким ім'ям, або створюю новий.)
Як мені розмістити всю цю логіку у своєму серіалізаторі / наборі даних?
Відповіді:
2 для відповіді № 1визначте поле тегу в серіалізаторі так:
tags = serializers.SlugRelatedField(slug_field="name", many=True)
Тепер щодо поведінки get_or_create моя пропозиціябуде використовувати форму django. Вам доведеться замінити метод post (або метод create, якщо ви використовуєте набір переглядів) і написати звичайний метод django для створення матеріалів за допомогою форм.
Подивіться на запит. DATA - це звичайний словник python, використовуйте його як дані для вашої форми стільця.
Форма прийме ці дані, і тоді ви зможете перевірити дані нормально, як і у формі django.
Потім створіть екземпляр крісла, використовуючи:
chair = form.save(commit=False)
chair.save()
Отримавши при собі екземпляр крісла, ви можете додати якомога більше тегів за допомогою:
chair.tags.add(tag1, tag2, tag3...)
Щоб отримати теги як об'єкти python, витягніть список імен тегів із запиту .DATA і передайте імена функції get_or_create. Ви можете зробити щось на зразок:
tags = []
tags_name_list = request.DATA["tags"]
for tag_name in tags_name_list:
tag = Tag.objects.get_or_create(name=tag_name)
tags.append(tag)
Тепер у вас є список тегів із собою. Додайте їх на стілець:
chair.tags.add(*tags)