IntegrityError:“ user_id”列中的空值违反了非空约束(Django Rest Framework)

时间:2018-11-04 16:21:59

标签: django python-3.x django-models django-rest-framework django-views

我是Django Rest Framework的新手,我遇到一个正在解决的完整性错误

简介:我有2个模型PatientEmbryo。 Patient是Django默认用户的ForeignKey。只有1个用户是SuperUser。所有患者均属于超级用户。每个病人可以有许多胚胎。我正在使用Django Rest Framework的ModelViewset

创建2个模型的视图
  

IntegrityError:“ user_id”列中的空值违反了非空约束

下面是我收到的错误消息的屏幕截图

enter image description here

下面是我的模型

class Patient(models.Model):
    """Patients model which has all the patients information"""
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    first_name = models.CharField(max_length=25)
    last_name = models.CharField(max_length=35)
    phone = models.CharField(max_length=18)
    email = models.EmailField(unique=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    @property
    def full_name(self):
        return "%s %s" % (self.first_name, self.last_name)

    def __str__(self):
        return self.email


class Embryo(models.Model):
    """A ForeignKey model to the patient"""
    patient = models.ForeignKey(Patient, on_delete=models.CASCADE)
    code_name = models.CharField(max_length=100)
    karyotype = models.CharField(max_length=100)
    down_syndrome = models.BooleanField(default=False)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    GENDER_CHOICES = (
        ("M", "Male"),
        ("F", "Female"),

    )
    sex = models.CharField(max_length=1, choices=GENDER_CHOICES)

    def __str__(self):
        return self.code_name

我使用ModelViewSet为我的模型创建实例下面是我的视图。

 class PatientsApiView(viewsets.ModelViewSet):
    """Handles Creating, reading and updating Patients"""

    serializer_class = serializers.PatientsSerializer
    queryset = Patient.objects.all()
    authentication_classes = (TokenAuthentication,)
    filter_backends = (filters.SearchFilter,)
    permission_classes = (IsAuthenticated,)
    search_fields = ("first_name", "last_name", "phone", "email",)

    def perform_create(self, serializer):
        serializer.save(user=self.request.user)


class EmbroApiView(viewsets.ModelViewSet):
    """Handles Creating, reading and updating Patients"""

    serializer_class = serializers.EmbryoSerializer
    queryset = Embryo.objects.all()
    authentication_classes = (TokenAuthentication,)
    filter_backends = (filters.SearchFilter,)
    permission_classes = (IsAuthenticated,)
    search_fields = ("code_name", "karyotype", "sex", "down_syndrome",)

    def perform_create(self, serializer):
        serializer.save(patient__id=self.kwargs['pk'])

以下是我的序列化程序。py

class PatientsSerializer(serializers.ModelSerializer):
    """A serializer for the patients model."""

    class Meta:
        model = Patient
        fields = ("id", "first_name", "last_name", "phone", "email")

    def create(self, validated_data):
        """Create and return a new patient"""

        patient = Patient(
            first_name=validated_data["first_name"],
            last_name=validated_data["last_name"],
            phone=validated_data["phone"],
            email=validated_data["email"]
        )
        patient.save()
        return patient


class EmbryoSerializer(serializers.ModelSerializer):
    class Meta:
        model = Embryo
        fields = ("id", "patient", "code_name", "karyotype", "down_syndrome", "sex")

        def create(self, validated_data):
            """Create and return a new embryo"""

            embryo = Embryo(
                code_name=validated_data["code_name"],
                karyotype=validated_data["karyotype"],
                down_syndrome=validated_data["down_syndrome"],
                sex=validated_data["sex"]
            )
            embryo.save()
            return embryo

我在做什么错了?

以下是@HåkenLid要求的回溯

Environment:


Request Method: POST
Request URL: http://127.0.0.1:8000/patient/

Django Version: 2.1.2
Python Version: 3.6.6
Installed Applications:
['django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'rest_framework',
 'rest_framework.authtoken',
 'patients']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']



Traceback:

File "/home/samir/PycharmProjects/GenomeVenv/lib/python3.6/site-packages/django/db/backends/utils.py" in _execute
  85.                 return self.cursor.execute(sql, params)

The above exception (null value in column "user_id" violates not-null constraint
DETAIL:  Failing row contains (4, Samir, Tendulkar, 2012795973, 2018-11-04 13:17:02.923723+00, 2018-11-04 13:17:02.923802+00, samnik_12345@hotmail.com, null).
) was the direct cause of the following exception:

File "/home/samir/PycharmProjects/GenomeVenv/lib/python3.6/site-packages/django/core/handlers/exception.py" in inner
  34.             response = get_response(request)

File "/home/samir/PycharmProjects/GenomeVenv/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
  126.                 response = self.process_exception_by_middleware(e, request)

File "/home/samir/PycharmProjects/GenomeVenv/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
  124.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "/home/samir/PycharmProjects/GenomeVenv/lib/python3.6/site-packages/django/views/decorators/csrf.py" in wrapped_view
  54.         return view_func(*args, **kwargs)

File "/home/samir/PycharmProjects/GenomeVenv/lib/python3.6/site-packages/rest_framework/viewsets.py" in view
  116.             return self.dispatch(request, *args, **kwargs)

File "/home/samir/PycharmProjects/GenomeVenv/lib/python3.6/site-packages/rest_framework/views.py" in dispatch
  495.             response = self.handle_exception(exc)

File "/home/samir/PycharmProjects/GenomeVenv/lib/python3.6/site-packages/rest_framework/views.py" in handle_exception
  455.             self.raise_uncaught_exception(exc)

File "/home/samir/PycharmProjects/GenomeVenv/lib/python3.6/site-packages/rest_framework/views.py" in dispatch
  492.             response = handler(request, *args, **kwargs)

File "/home/samir/PycharmProjects/GenomeVenv/lib/python3.6/site-packages/rest_framework/mixins.py" in create
  21.         self.perform_create(serializer)

File "/home/samir/PycharmProjects/genomic_prediction/src/genomic_project/patients/views.py" in perform_create
  51.         serializer.save(user=self.request.user)

File "/home/samir/PycharmProjects/GenomeVenv/lib/python3.6/site-packages/rest_framework/serializers.py" in save
  214.             self.instance = self.create(validated_data)

File "/home/samir/PycharmProjects/genomic_prediction/src/genomic_project/patients/serializers.py" in create
  21.         patient.save()

File "/home/samir/PycharmProjects/GenomeVenv/lib/python3.6/site-packages/django/db/models/base.py" in save
  718.                        force_update=force_update, update_fields=update_fields)

File "/home/samir/PycharmProjects/GenomeVenv/lib/python3.6/site-packages/django/db/models/base.py" in save_base
  748.             updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)

File "/home/samir/PycharmProjects/GenomeVenv/lib/python3.6/site-packages/django/db/models/base.py" in _save_table
  831.             result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)

File "/home/samir/PycharmProjects/GenomeVenv/lib/python3.6/site-packages/django/db/models/base.py" in _do_insert
  869.                                using=using, raw=raw)

File "/home/samir/PycharmProjects/GenomeVenv/lib/python3.6/site-packages/django/db/models/manager.py" in manager_method
  82.                 return getattr(self.get_queryset(), name)(*args, **kwargs)

File "/home/samir/PycharmProjects/GenomeVenv/lib/python3.6/site-packages/django/db/models/query.py" in _insert
  1136.         return query.get_compiler(using=using).execute_sql(return_id)

File "/home/samir/PycharmProjects/GenomeVenv/lib/python3.6/site-packages/django/db/models/sql/compiler.py" in execute_sql
  1289.                 cursor.execute(sql, params)

File "/home/samir/PycharmProjects/GenomeVenv/lib/python3.6/site-packages/django/db/backends/utils.py" in execute
  100.             return super().execute(sql, params)

File "/home/samir/PycharmProjects/GenomeVenv/lib/python3.6/site-packages/django/db/backends/utils.py" in execute
  68.         return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)

File "/home/samir/PycharmProjects/GenomeVenv/lib/python3.6/site-packages/django/db/backends/utils.py" in _execute_with_wrappers
  77.         return executor(sql, params, many, context)

File "/home/samir/PycharmProjects/GenomeVenv/lib/python3.6/site-packages/django/db/backends/utils.py" in _execute
  85.                 return self.cursor.execute(sql, params)

File "/home/samir/PycharmProjects/GenomeVenv/lib/python3.6/site-packages/django/db/utils.py" in __exit__
  89.                 raise dj_exc_value.with_traceback(traceback) from exc_value

File "/home/samir/PycharmProjects/GenomeVenv/lib/python3.6/site-packages/django/db/backends/utils.py" in _execute
  85.                 return self.cursor.execute(sql, params)

Exception Type: IntegrityError at /patient/
Exception Value: null value in column "user_id" violates not-null constraint
DETAIL:  Failing row contains (4, Samir, Tendulkar, 2012795973, 2018-11-04 13:17:02.923723+00, 2018-11-04 13:17:02.923802+00, samnik_12345@hotmail.com, null).

我将用户添加到序列化器中,请参见下图,并删除了以下代码,但错误仍然相同

def perform_create(self, serializer):
        serializer.save(user=self.request.user)

enter image description here

Views

enter image description here

1 个答案:

答案 0 :(得分:3)

您的PatientsSerializer.create方法会从序列化程序输入数据中丢弃user字段。

def create(self, validated_data):
    """Create and return a new patient"""

    patient = Patient(
        first_name=validated_data["first_name"],
        last_name=validated_data["last_name"],
        phone=validated_data["phone"],
        email=validated_data["email"]
        # you need a `user` as well.
    )
    patient.save()
    return patient

目前还不清楚为什么要使用自定义创建方法。您是否尝试过将其从序列化程序中删除?默认的ModelSerializer.create方法使用整个validated_data字典。只需将user添加到PatientsSerializer.Meta.fields

class PatientsSerializer(serializers.ModelSerializer):
    """A serializer for the patients model."""

    class Meta:
        model = Patient
        fields = ("id", "user', "first_name", "last_name", "phone", "email")