我有2个表,一个信息表和一个查找表。已连接到邮政数据库
class Lookup(models.Model):
lookup=models.CharField(max_length=50)
class Info(models.Model):
multiChoice = ArrayField(models.IntegerField(blank=True),null=True)
我是否可以在多选字段上创建一个引用约束,以便字段上的每个值必须是查找表的 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帮助。我在资源水合物方法上做了类似的事情。
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