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


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

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


8963
2018-04-09 14:01


起源



答案:


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


13
2018-04-09 14:16



不会输入 model 被作业覆盖 field_object, model_direct, m2m = ...? - alvas
我猜,但它从未再次使用,所以没什么大不了的。 - John Montgomery


答案:


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


13
2018-04-09 14:16



不会输入 model 被作业覆盖 field_object, model_direct, m2m = ...? - alvas
我猜,但它从未再次使用,所以没什么大不了的。 - John Montgomery


我遇到了相同的用例,接受的答案对我来说并不直接。我正在使用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字段的名称。干杯!


1
2018-06-12 16:49





简单的一个班轮找到与其他的所有关系 models 存在于 model

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

以上将给出一个 list 所有的 models 和他们的 relations

例:

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

1
2018-03-17 12:31





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

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

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

0
2018-04-09 14:14



谢谢,如果我没有特殊要求,我会这样做:我的所有“表单”都是由JS驱动的内联编辑表单。这使用Django的API生成它们是一个很大的挑战,我不太愿意接受它。 - balu