class RestockNotification(models.Model):
email = models.EmailField(max_length=255, null=True, blank=True)
whatsapp_number = models.CharField(
max_length=255, null=True, blank=True, validators=[validate_phone_number]
)
product_entry = models.ForeignKey(
"ProductEntry", on_delete=models.CASCADE, related_name="product_notifications"
)
class Meta:
constraints = [
UniqueConstraint(
fields=['email', 'product_entry'],
condition=models.Q(email__isnull=False),
name='unique_email_with_product'
),
UniqueConstraint(
fields=['whatsapp_number', 'product_entry'],
condition=models.Q(whatsapp_number__isnull=False),
name='unique_whatsapp_number_with_product'
),
]
the UniqueConstraint not apply uniqueness over (email,ProductEntry) and (whatsapp_number,ProductEntry) as expected, and i can create duplicated instances!!
here is an example of my data:
product_entry = ProductEntry.objects.get(id=1)
obj = RestockNotification.objects.create(
email="omar.raafat@bit68.com",
product_entry=product_entry,
)
I have executed the create operation multiple times in my shell and it works each time and create new instance!! what i am doing wrong??
I am using Django 2.2.16 and python 3.12 and my database is MySQL 5.7
I have tried this in my test lab and I am unable to recreate the symptoms you describe here. Any attempt to repeat the create
, fails.
Please verify this as being accurate. Django 2.2 is beyond its End-Of-Life date, and is not compatible with Django 3.12.
If you’re actually using Django 4.2 and this is just a typo, please identify which subversion of 4.2 you are using, because 4.2 does not support Python 3.12 until 4.2.8. (See FAQ: Installation | Django documentation | Django)
Also please verify that you have done a makemigrations
and migrate
after adding these constraints.
hello,
I am already using Django 2.2.16 and latest version of python 3.12.2 on docker and MySQL 5.7 as my database and i guess the issue came from MySQL support for conditional unique constraint.
And yes i have done the makemigrations
and migrate
commands.
Thanks a lot,
if can i ask another question, may I ask about how to handle the error returns from the UinqueContraint as it returns 500, where can i override it and handle it correctly with Django 2.2.16 as u can’t upgrade my project now?
I’d remove the constraint. I can’t see any reason to have it present if it’s not going to work in your environment.
1 Like
what do you suggest to me to use instead of the constraint ?
That depends upon how you are adding data and the number of different places in your code that data gets added to that model.
If all additions are being made in one location in your code (one view or one function being called by views), you could add the test for a duplicate entry in that location using get_or_create
, along with whatever other conditions you wish to enforce.
If you’re adding data to this model in multiple locations through your system, but still relying on create
, then you could override the model’s save
method and handle this there.
Unfortunately, neither of the two methods above will work with a bulk_create
or bulk_update
- both of which bypass the individual model methods. In this situation, you’re out of luck. You’ll either need to convert your process using those methods to other methods, or change how you’re creating the instances to be added (or updated) to test for validity of those entries.
1 Like
i have only one view that creates an instance only, so i see there are three options:
1- overriding clean
method of the model.
2- move this logic in serialzier's validate
method
3- using before_create
hook