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()
.
So in practice, do this
class SomeModel(models.Model):
date = models.DateField()
text = models.CharField()
def save(self, *args, **kwargs):
if self.objects.filter(date=self.date, text=self.text).exists():
raise ValidationError({'text': 'Must be unique for date.'})
return super().save(*args, **kwargs)
Instead of this
class SomeModel(models.Model):
date = models.DateField()
text = models.CharField(unique_for='date')
Django Doctor will run this check by default. No configuration is needed but the check can be turned on/off using check code brittle-unique-for
in your pyproject.toml file.