Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Usage of unique_for_date

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()
like image 940
Dmitry Oleinik Avatar asked Jul 09 '17 20:07

Dmitry Oleinik


People also ask

What is null false in Django?

null. If True , Django will store empty values as NULL in the database. Default is False .

What is Auto_now_add in Django?

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 slug field in Django?

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.


2 Answers

I think that you are having created as DateTimeField , so it is considering time also. Try changing it to DateField

like image 50
Adaikalaraj Avatar answered Sep 16 '22 13:09

Adaikalaraj


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.

like image 22
zaidfazil Avatar answered Sep 16 '22 13:09

zaidfazil