Shiv
Shiv

Reputation: 342

Django: Is there a way to add a foreign key field to "unique_together"?

I want to be able to make a model unique on a value that comes from a foreign key model. Not sure if that's possible in django.

Example: I have a model A as:

class modelA(models.Model):
    fieldA1 = models.AutoField(primary_key=True)
    fieldA2 = models.CharField(max_length=20)

And also model B as:

class modelB(models.Model):
    fieldB1 = models.CharField(max_length=20)
    fieldB2 = models.ForeignKey(modelA)

    class Meta:
        unique_together = ('fieldB1', 'fieldB2',<<'fieldA2'>>)

I want to add fieldA2 as one of the attributes in the unique_together clause of model B. Is that possible in Django? I COULD NOT do it as-

unique_together = ('fieldB1', 'fieldB2','modelA__fieldA2')

Upvotes: 5

Views: 4515

Answers (2)

ekauffmann
ekauffmann

Reputation: 150

You can override modelB's clean method like this

class ModelB(models.Model):
    fieldB1 = models.CharField(max_length=20)
    fieldB2 = models.ForeignKey(modelA)

    def clean(self):
        """
        Validate 'fieldB1', 'fieldB2' and 'fieldB2__fieldA2' are unique together
        """
        # first, check that foreign keys fields exist. Must use '_id', or else a RelatedObjectDoesNotExist error will be raised
        if self.fieldB2_id and self.fieldB2.field_A2_id:
            if self.__class__.objects.filter(fieldB1=self.fieldB1, fieldB2=self.fieldB2, fieldB2__fieldA2=self.fieldB2.fieldA2).exists():
                raise ValidationError(
                    _('Instance of ModelB with fieldB1, fieldB2 and fieldB2.fieldA2 already exists.'),
                    code='unique_together',
                )

Upvotes: 0

doniyor
doniyor

Reputation: 37846

you cannot. database constraints cannot contain those kind of data. you will have to check it programmatically before creating instances or write some validator

Upvotes: 4

Related Questions