首页 文章

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

提问于
浏览
11

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

// 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 回答

  • 1

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

    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]
    

    上面将给出 models 所有 modelsrelations .

    Example:

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

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

  • 0

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

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

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

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

相关问题