I'm trying to use unique_for_date option to prevent creating multiple posts with the same slug for the same date. But it doesn't seem to work at all: I still can create posts with the same slug from the shell and admin dashboard. The same goes for ModelForm. My models.py:
class Post(models.Model):
STATUS_CHOICES = (
('draft', 'Draft'),
('published', 'Published'),
('suspended', 'Suspended'),
)
title = models.CharField(max_length=200)
slug = models.SlugField(max_length=200, unique_for_date='created')
status = models.CharField(max_length=15,
choices=STATUS_CHOICES,
default='draft')
content = models.TextField(max_length=200000, blank=True)
# dates
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
publish = models.DateTimeField(default=timezone.now)
I've found some kind of a workaround for problem by changing auto_now_add=True
to default=timezone.now
but it only shows error while creating object via django admin - still no errors while creating objects from shell or form.
Update: I know that using auto_now_add sets editable=False causing django to skip field validation, but it doesn't explain why it skips validation even with default=timezone.now
Update 2: For some reason unique_for_date works only for django-admin dashboard forms (in my case at least). To get the same effect for other forms I've overridden the clean_fields method of the model (forces django to validate unique fields):
def clean_fields(self, exclude=None):
super().clean_fields(exclude=exclude)
self.validate_unique()
null. If True , Django will store empty values as NULL in the database. Default is False .
The auto_now_add will set the timezone. now() only when the instance is created, and auto_now will update the field everytime the save method is called. It is important to note that both arguments will trigger the field update event with timezone.
What is SlugField in Django? It is a way of generating a valid URL, generally using data already obtained. For instance, using the title of an article to generate a URL. Let's assume our blog have a post with the title 'The Django book by Geeksforgeeks' with primary key id= 2.
I think that you are having created
as DateTimeField
, so it is considering time also. Try changing it to DateField
The unique_for_date
constraint is enforced at the Django admin-form level but not at the database level. If you look at the docs,
This is enforced by Model.validate_unique() during model validation but not at the database level. If any unique_for_date constraint involves fields that are not part of a ModelForm (for example, if one of the fields is listed in exclude or has editable=False), Model.validate_unique() will skip validation for that particular constraint.
If you need to enforce a database level unique constraint, then I may suggest adding a unique_together
constraint in your Meta
class. Also, you may need to change your created
field to a DateField()
, if you may consider.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With