django.db.utils.Ошибка целостности: сбой ненулевого ограничения — drf_writable_nested

#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. Кроме того, все функции предопределены, пользователь не будет создавать пользовательскую функцию.