I worked with django rest framework a lot and everything worked fine until today. The same function suddenly returns something different. I have a unique together on my client model with name and company. I recently created a mixin called AutoCompany which automatically sets the company on the client.
My client model:
class Client(AutoCompany):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
name = models.CharField(max_length=155)
description = models.TextField(blank=True)
class Meta:
constraints = [
models.UniqueConstraint(fields=["name", "company"], name="Name and company"),
]
AutoCompany
class AutoCompany(models.Model):
company = models.ForeignKey("company.Company", models.DO_NOTHING)
def save(self, *args, **kwargs):
company = apps.get_model("company.Company")
try:
self.company
except company.DoesNotExist:
self.company = get_request().user.company
self.after_company_set()
return super().save(*args, **kwargs)
def after_company_set(self):
pass
class Meta:
abstract = True
So previously when I created a client with the same name for the same company I got a 400 response with this error:
The fields name, company must make a unique set.
My serializer looks like this:
class ClientSerializer(serializers.ModelSerializer):
class Meta:
model = models.Client
fields = ["id", "name", "description"]
But now I just get a 500 response with a python error. It seems like the error is not caught anymore. Now I just get:
django.db.utils.IntegrityError: (1062, "Duplicate entry 'test-cafd0ed10f9f4865a1d56abb67daa831' for key 'Name and company'")
Does anybody know why this change occurred?
DRF doesn't validate UniqueConstraints the way it does unique_together.
The reason for this is because unique constraints can be more complex than just "this collection of fields must have unique values". Consider the following:
UniqueConstraint(
fields=["author", "slug"],
condition=Q(status="published"),
name="author_slug_published_uniq",
)
This constraint only validates that the row is unique if the status is published, i.e. there can be multiple rows with the same slug and author if they are all drafts. Because of this complexity, there isn't a validator for this. However, for this simple case, you can add DRF's UniqueTogether validator manually:
class ClientSerializer(serializers.ModelSerializer):
class Meta:
fields = ["id", "name", "description", "company"]
validators = [
UniqueTogetherValidator(
queryset=Client..objects.all(),
fields=["name", "company"],
)
]
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