1

I have 2 tables, a info table and a lookup table. Connected to a postgres DB

class Lookup(models.Model):
    lookup=models.CharField(max_length=50)

class Info(models.Model):
     multiChoice = ArrayField(models.IntegerField(blank=True),null=True)

Can I create a referential constraint on the multiChoice field such that each value on the field must be one of the ID's of the Lookup table.

Something like this - http://blog.2ndquadrant.com/postgresql-9-3-development-array-element-foreign-keys/

2 Answers 2

2

Unfortunately in Postgres 9.3, you won't be able to add a foreign key constraint on the array field. See this answer for more details.

However, you can perform some level of validation within Django models, for example:

class Info(models.Model):        
    ...
    def save(self, *args, **kwargs):
        # validate all multiChoice belong in lookup
        lookup_id_list = Lookup.objects.filter(id__in=self.multiChoice)\
            .values_list('id', flat=True)
        assert set(lookup_id_list) == set(self.multiChoice)
        super(Info, self).save(*args, **kwargs)

Note that this won't prevent someone from creating/updating Info records in the database directly which violate your "constraint".

If your models are in a many-to-many relationship, the correct solution would be to use a ManyToMany field which can guarantee your constraint will not be violated.

Sign up to request clarification or add additional context in comments.

Comments

0

Thanks for the help @Derek Kwok. I did somthing similar on the Resource hydrate method.

def hydrate(self,bundle):
    #Get the array values from the request bundle eg: "{1,2,3}"
    multiChoiceValues=bundle.data['multiChoice'][1:-1].split(',')
    #Get the lookup table values from DB
    lookupObjs=Lookup.objects.all()
    
    #Compare them
    #todo: Improve loop comparisons
    for multiChoice in multiChoiceValues:
        found=False
        for objs in lookupObjs:
            if (multiChoice==''+repr(objs.id)):
                found=True
                break
        if (found==False):
            #Raise an error if any of the values passed break the referential constraint
            raise IntegrityError
    return bundle

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.