如何确定模型列是否为外键?

时间:2010-04-09 14:01:03

标签: python django foreign-keys

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

// 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()关键栏?

4 个答案:

答案 0 :(得分:13)

您可以在模型_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')

答案 1 :(得分:3)

简单的一行,找到models中存在的与model的所有关系:

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]

以上将list的所有models及其relations。{/ p>

示例:

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

答案 2 :(得分: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

这是在类中定义的方法。对于我的情况,我需要的是ForeignKey字段的名称。干杯!

答案 3 :(得分:0)

浏览“ModelChoiceField”字段。他们能否解决您将外键放入表格的问题;而不是自己这样做。

http://docs.djangoproject.com/en/1.1/ref/forms/fields/#fields-which-handle-relationships

record = forms.ModelChoiceField(queryset=table_obj.objects.all())