Django中不要求参照完整性的ForeignKey?
我想在Django模型中设置一个ForeignKey
字段,这个字段有时候指向另一张表。但我希望能在这个字段中插入一个ID,这个ID可能指向另一张表中的某个条目,而这个条目不一定存在。所以如果在另一张表中找到了这个条目,我希望能享受到ForeignKey关系带来的所有好处。但如果没有找到,我希望这个字段就仅仅被当作一个数字来处理。
这可能吗?这就是所谓的通用关系吗?
6 个回答
这其实很简单,就是声明一个外键(ForeignKey),然后创建这个列,但不把它真正声明为外键。这样的话,如果对象存在,你就可以用 o.obj_id 和 o.obj 来访问它;如果你试图加载一个不存在的对象,系统会抛出一个异常(大概是 DoesNotExist
)。
不过,我觉得没有办法让 syncdb
自动帮你做到这一点。我发现 syncdb
的功能有限,甚至有点没用,所以我完全绕过它,自己写代码来创建数据库结构。你可以先用 syncdb
创建数据库,然后直接修改表,比如用 ALTER TABLE tablename DROP CONSTRAINT fk_constraint_name
来去掉外键约束。
当然,这样做的话,你也会失去 ON DELETE CASCADE 和所有的引用完整性检查。
我刚开始学习Django,所以不太确定它是否自带你想要的功能。我想到的一个方法是这样的:
from django.db import models
class YourModel(models.Model):
my_fk = models.PositiveIntegerField()
def set_fk_obj(self, obj):
my_fk = obj.id
def get_fk_obj(self):
if my_fk == None:
return None
try:
obj = YourFkModel.objects.get(pk = self.my_fk)
return obj
except YourFkModel.DoesNotExist:
return None
我不确定你是否在使用Django自带的管理应用。如果用PositiveIntegerField代替ForeignKey,这样在管理网站上这个字段就会显示为一个文本输入框。
这个问题很早以前就有人问过了,但现在对于新手来说,有一种简单的方法可以处理这个问题,就是在你的外键(ForeignKey)上设置 db_constraint=False。
customer = models.ForeignKey('Customer', db_constraint=False)
或者,如果你希望这个外键可以为空,并且不强制要求引用完整性的话:
customer = models.ForeignKey('Customer', null=True, blank=True, db_constraint=False)
我们在一些情况下使用这个方法,因为我们无法保证这些关系会按照正确的顺序创建。
编辑:更新了链接