#35848: Problem with UniqueConstraint on fields, one of which allows NULL value.
-------------------------------------+-------------------------------------
     Reporter:  Андрей               |                    Owner:  (none)
         Type:  Bug                  |                   Status:  closed
    Component:  Database layer       |                  Version:  5.1
  (models, ORM)                      |               Resolution:
     Severity:  Normal               |  worksforme
     Keywords:  UniqueConstraint,    |             Triage Stage:
  nullable, null                     |  Unreviewed
    Has patch:  0                    |      Needs documentation:  0
  Needs tests:  0                    |  Patch needs improvement:  0
Easy pickings:  0                    |                    UI/UX:  0
-------------------------------------+-------------------------------------
Comment (by Андрей):

 You are right that when Django is running through the SHELL, the error is
 not reproduced (I checked it too after your message).
 However, there is an error when creating an object using the rest api.
 The order is as follows:
 1. Create any ''measure'' object (m1. **This can be created using shell**
 ).
 2. Create ''mymodel'' with the parameter measure = null (name="test".
 **This can be created using shell** ).
 3. Create ''mymodel'' from rest api (name="test", parameter=m1.  **This
 should be created via the viewset, in our case the rest api via
 postman/bruno** ).
 I get the error:

 {{{
 {
 "name": [
 "my model with that name already exists."
   ]
 }
 }}}

 My scripts:

 **models.py**
 {{{
 from django.db import models
 from django.db.models import Q


 class Measure(models.Model):

     id = models.AutoField(
         primary_key=True,
         verbose_name="Key",
     )
     code = models.CharField(
         max_length=5,
         unique=True,
         verbose_name="Code",
         error_messages={"unique": "Err msg."},
     )

     def __str__(self):
         return self.code


 class MyModel(models.Model):

     id = models.BigAutoField(primary_key=True, editable=False)
     name = models.CharField(max_length=1000, verbose_name="Name")
     measure = models.ForeignKey(
         Measure,
         related_name="mymodel_measure",
         on_delete=models.SET_NULL,
         null=True,
         blank=True,
         verbose_name="Measure",
     )

     def __str__(self):
         return self.name

     class Meta:
         constraints = [
             models.UniqueConstraint(
                 fields=["name"],
                 name="mymodel_unique_name_measure_null",
                 condition=Q(measure__isnull=True),
                 violation_error_message="Error message for null",
             ),
             models.UniqueConstraint(
                 fields=["name", "measure"],
                 name="mymodel_unique_name_measure_not_null",
                 condition=Q(measure__isnull=False),
                 violation_error_message="Error message for not null",
             ),
         ]

 }}}

 **views.py**
 {{{
 from rest_framework import viewsets
 from directories.serializers import MyModelSerializer
 from .models import MyModel

 class MyModelViewSet(viewsets.ModelViewSet):
     queryset = MyModel.objects.select_related("measure").all()
     serializer_class = MyModelSerializer
 }}}

 **serializers.py**
 {{{
 from rest_framework import serializers
 from directories.models import MyModel

 class MyModelSerializer(serializers.ModelSerializer):

     class Meta:
         model = MyModel
         fields = "__all__"

 }}}

 **urls.py**
 {{{
 from django.urls import path, include
 from rest_framework.routers import DefaultRouter
 from directories.views import MyModelViewSet


 router = DefaultRouter()
 router.register("mymodel", MyModelViewSet)


 urlpatterns = [
     path("d/", include(router.urls)),
 ]

 }}}

 Next in postman or bruno create object (step 3):
 post method, body:
 {{{
 {
   "name": "test",
   "measure": 1
 }
 }}}
 and I get an error:
 {{{
 {
 "name": [
 "my model with that name already exists."
   ]
 }
 }}}
-- 
Ticket URL: <https://code.djangoproject.com/ticket/35848#comment:4>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/0107019299f079d8-7a3f493a-2a82-4406-a32d-8d9c94a5d1e6-000000%40eu-central-1.amazonses.com.

Reply via email to