繁体   English   中英

带有 postgres 引用约束的 Django Arrayfield

[英]Django Arrayfield with referential constraint for postgres

我有 2 个表,一个信息表和一个查找表。 连接到 postgres 数据库

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

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

我可以在 multiChoice 字段上创建一个引用约束,以便该字段上的每个值都必须是 Lookup 表的 ID 之一。

像这样的 - http://blog.2ndquadrant.com/postgresql-9-3-development-array-element-foreign-keys/

不幸的是,在 Postgres 9.3 中,您将无法在数组字段上添加外键约束。 有关更多详细信息,请参阅此答案

但是,您可以在 Django 模型中执行某种级别的验证,例如:

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)

请注意,这不会阻止某人直接在数据库中创建/更新违反您的“约束”的信息记录。

如果您的模型处于多对多关系,正确的解决方案是使用ManyToMany字段,它可以保证您的约束不会被违反。

感谢@Derek Kwok 的帮助。 我在 Resource hydrate 方法上做了类似的事情。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM