如何判断模型的列是否是外键?

18 投票
5 回答
11215 浏览
提问于 2025-04-15 21:25

我正在根据请求动态地在数据库中存储信息:

// table, id and column are provided by the request
table_obj = getattr(models, table)
record = table_obj.objects.get(pk=id)

setattr(record, column, request.POST['value'])

问题是,request.POST['value'] 有时候会包含一个外部记录的主键(也就是一个整数),而 Django 期望这个列的值是一个 ForeignModel 类型的对象:

无法分配 "u'122'": "ModelA.b" 必须是一个 "ModelB" 实例。

现在,有没有简单的方法可以动态检查 b 是否是一个包含外键的列,以及这些外键链接到哪个模型?(这样我就可以通过主键加载外部记录并将其分配给 ModelA?)还是说 Django 没有提供这样的信息给程序员,所以我真的需要自己动手,使用 isinstance() 来检查外键列?

5 个回答

1

我遇到了同样的问题,但那个被认可的答案对我来说直接没用。我用的是Django 1.2,如果这有关系的话。于是,我用了get_field_by_name这个方法,具体用法如下。

def get_foreign_keys(self):
        foreign_keys = []
        for field in self._meta.fields:
            if isinstance(self._meta.get_field_by_name(field.name)[0], models.ForeignKey):
                foreign_keys.append(field.name)

        if not foreign_keys:
            return None
        return foreign_keys

这个方法是在一个类里面定义的。对我来说,我需要的是外键字段的名称。谢谢!

6

这里有一个简单的一行代码,可以用来找到一个模型与其他模型之间的所有关系:

In [8]: relations = [f for f in Model._meta.get_fields() if (f.many_to_one or f.one_to_one) and f.auto_created]

上面的代码会返回一个列表,里面包含了所有模型及其关系

举个例子:

In [9]: relations
Out[9]:
[<ManyToOneRel: app1.model1>,
 <ManyToOneRel: app2.model1>,
 <OneToOneRel: app1.model2>,
 <OneToOneRel: app3.model5>,
 <OneToOneRel: app5.model1>]
15

你可以在模型的 _meta 对象上使用 get_field_by_name 方法:


from django.db.models import ForeignKey

def get_fk_model(model, fieldname):
    """Returns None if not foreignkey, otherswise the relevant model"""
    field_object, model, direct, m2m = model._meta.get_field_by_name(fieldname)
    if not m2m and direct and isinstance(field_object, ForeignKey):
        return field_object.rel.to
    return None

假设你有一个模型类叫 MyModel,你可以这样使用:


fk_model = get_fk_model(MyModel, 'fieldname')

撰写回答