unique_for_date/month/year is very brittle and over time will likely be a source for unexpected behaviour.
unique_for_date/month/year prevents entry of two records with the same value on the same date or month or year.
However, this feature is unfortunately brittle:
Model.validate_unique() and so will not occur if Model.save() is called without first calling Model.validate_unique().Model.validate_unique() is called when using a ModelForm that does not include a field involved in the check.DateTimeField.Most of these problems can be mitigated by moving the validation to Model.save().
If our GitHub code review bot spots this issue in your pull request it gives this advice:
1 | + | class ExampleModel(models.Model): | |
2 | + | date = models.DateField() | |
3 | + | foo = models.CharField(unique_for_date='date') |
unique_for_date/month/year is very brittle and over time will likely be a source for unexpected behaviour.
- | foo = models.CharField(unique_for_date='date') |
+ | foo = models.CharField() |
+ | |
+ | def save(self, *args, **kwargs): |
+ | # more verbose, but less brittle than unique_for_date |
+ | if self.objects.filter(date=self.date, foo=self.foo).exists(): |
+ | raise ValidationError({'foo': 'Must be unique for date.'}) |
+ | return super().save(*args, **kwargs) |



