#python #django #django-rest-framework
#python #django #django-rest-framework
Вопрос:
Создал простое приложение, которое позволяет мне создавать клиентов, а затем также добавлять список функций в виде поля (у которого есть несколько параметров).
models.py
from django.db import models
class Feature(models.Model):
feature1 = models.BooleanField(default=None)
feature2 = models.BooleanField(default=None)
feature3 = models.BooleanField(default=None)
class Client(models.Model):
client_name = models.CharField(max_length=200)
org_id = models.CharField(max_length=100)
date_created = models.CharField(max_length=100)
features = models.ManyToManyField(Feature, related_name='client_list')
serializers.py
from rest_framework import serializers
from .models import Client, Feature
from drf_writable_nested import WritableNestedModelSerializer
class featureSerializer(serializers.ModelSerializer):
class Meta:
model = Feature
fields = ('feature1', 'feature2', 'feature3')
class clientSerializer(WritableNestedModelSerializer):
features = featureSerializer(many=True)
class Meta:
model = Client
fields = ('id', 'client_name', 'org_id', 'date_created', 'features')
оболочка python
>>> data = {'client_name': 'Test Client XYZ', 'org_id': '001', 'date_created': '2018-03-06', 'features': [{'feature1': True}, {'feature2': False}, {'Feature3': True},],}
>>> serializer = clientSerializer(data=data)
>>> serializer.is_valid()
True
>>> print(serializer)
clientSerializer(data={'client_name': 'Test Client XYZ', 'org_id': '001', 'date_created': '2018-03-06', 'features': [{'feature1': True}, {'feature2': False}, {'feature3': True}]}):
id = IntegerField(label='ID', read_only=True)
client_name = CharField(max_length=200)
org_id = CharField(max_length=100)
date_created = CharField(max_length=100)
features = featureSerializer(many=True):
feature1 = BooleanField(required=False)
feature2 = BooleanField(required=False)
feature3 = BooleanField(required=False)
>>> print(serializer.data)
{'client_name': 'Test Client XYZ', 'org_id': '001', 'date_created': '2018-03-06', 'features': [OrderedDict([('feature1', True)]), OrderedDict([('feature2', False)]), OrderedDict([('feature3', True)])]}
но когда я на самом деле иду на сохранение, используя:
>>> client = serializer.save()
Я получаю следующую ошибку:
django.db.utils.IntegrityError: NOT NULL constraint failed: client_feature.feature2
Я понятия не имею, почему это не сохраняется. Похоже, что в Feature2 генерируется ошибка, для которой я передал значение False. Мы будем очень признательны за любую помощь. Изначально я собирался использовать DRF API для создания данных, но понял, что он не поддерживает списки, поэтому я не смог ввести часть функций клиента. Вот почему я использовал пакет drf_writable_nested.
Комментарии:
1. когда вы настраиваете свои функции, можете ли вы поместить все в один и тот же dict? Нравится
[{'feature1': True, 'feature2': False, 'feature3': True}]
. Похоже, вы устанавливаете 3 объекта features. Я не понимаю, зачем вам здесь нужен список.2. ДА! Это сработало! Я следил за документацией из drf_writable_nested ( github.com/beda-software/drf-writable-nested ) который отформатировал его со словарем для каждого элемента… странно.
3. хм, я почти уверен, что у них нет одного и того же класса.
Ответ №1:
Как я уже писал в своем комментарии, вы допускаете ошибку в документеhttps://github.com/beda-software/drf-writable-nested и ваша концепция.
Здесь у вас есть класс с тремя полями :
class Feature(models.Model):
feature1 = models.BooleanField(default=None)
feature2 = models.BooleanField(default=None)
feature3 = models.BooleanField(default=None)
Итак, когда вы создавали свой экземпляр, вы создавали одну функцию с набором feature1, но не feature2 или feature3, затем функцию с набором feature2, но не feature1 или feature3 и т.д…
Вот почему я почти уверен, что в вашем случае вам не нужен список, поскольку в вашем объекте есть все функции.
В примере, который вы указали, просто объявляется несколько сайтов. Например, у вас было :
class Feature(models.Model):
name = models.CharField(max_size=255)
Вы могли бы сделать:
'features': [{'name': 'feature1'}, {'name': 'feature2'}, {'name': 'feature3'}...
]
Важно, чтобы вы это понимали.
Здесь я даже не знаю, нужна ли вам ManyToMany
связь.
Комментарии:
1. Моей целью было в конечном итоге создать форму, в которой кто-то мог бы создать клиента, и там был бы список из 10 функций (все логические), которые были бы добавлены к объекту client при отправке. Было бы проще просто создать класс объектов с простым именем и логическим полем, а затем вызвать его несколько раз, изменив имя во внешнем интерфейсе?
2. Кроме того, все функции предопределены, пользователь не будет создавать пользовательскую функцию.