在Django中获取模型的字段

Get model's fields in Django

给定一个django模型,我将尝试列出它的所有字段。我已经看到一些使用元模型属性的例子,但是元前面的下划线是否表示元属性是私有属性,不应该直接访问?…因为,例如,meta的布局将来可能会改变,而不是一个稳定的API?

元是这个规则的例外吗?它是稳定的,随时可以使用,还是被认为是不好的做法?或者,是否有一个函数或其他方法可以在不使用元属性的情况下内省模型的字段?下面是一些链接的列表,这些链接显示了如何使用u meta属性执行此操作。

任何建议都非常感谢。

Django对象获取/设置字段

http://www.djangofoo.com/80/get-list-model-fields

如何反省姜戈模型场?


_meta是私有的,但相对稳定。目前正在努力使其正式化、记录并删除下划线,这可能发生在1.3或1.4之前。我想我们会努力确保事情是向后兼容的,因为很多人都在使用它。

如果您特别关注兼容性,请编写一个接受模型并返回字段的函数。这意味着,如果将来有什么东西改变了,你只需要改变一个函数。

1
2
def get_model_fields(model):
    return model._meta.fields

我相信这将返回一个Field对象的列表。要从实例中获取每个字段的值,请使用getattr(instance, field.name)

更新:Django的贡献者们正在开发一个API来替换作为谷歌夏季代码一部分的meta对象。见:-https://groups.google.com/forum/!主题/django开发者/hd4rozq0wyk-https://code.djangoproject.com/wiki/new_-meta_-api


我知道这篇文章已经很老了,但我只是想告诉那些正在寻找同样东西的人,有一个公共的和官方的API可以做到这一点:get_fields()get_field()

用途:

1
2
fields = model._meta.get_fields()
my_field = model._meta.get_field('my_field')

https://docs.djangoproject.com/en/1.8/ref/models/meta/


这是Django自己在从模型构建表单时所做的事情。它使用的是元属性,但正如Bernhard指出的,它同时使用元字段和元多属性。查看django.forms.models.fieldsforu model,您可以这样做:

1
2
3
opts = model._meta
for f in sorted(opts.fields + opts.many_to_many):
    print '%s: %s' % (f.name, f)


现在有一种特殊的方法-get_fields()。

1
2
    >>> from django.contrib.auth.models import User
    >>> User._meta.get_fields()

它接受两个可用于控制返回哪些字段的参数:

  • 包括家长

    默认为true。递归地包含在父类上定义的字段。如果设置为false,get_fields()将只搜索直接在当前模型上声明的字段。直接从抽象模型或代理类继承的模型中的字段被视为本地字段,而不是父类字段。

  • 包括隐藏的

    默认为false。如果设置为true,get_field s()将包括用于支持其他字段功能的字段。这还包括以"+"开头的任何具有相关"名称"(例如manytomanyfield或foreignkey)的字段。


get_fields()返回tuple类型,每个元素都是Model field类型,不能直接用作字符串。因此,field.name将返回字段名

埃多克斯1〔9〕上面的代码将返回一个包含所有字段名称的列表例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
In [11]: from django.contrib.auth.models import User

In [12]: User._meta.get_fields()
Out[12]:
(<ManyToOneRel: admin.logentry>,
 <django.db.models.fields.AutoField: id>,
 <django.db.models.fields.CharField: password>,
 <django.db.models.fields.DateTimeField: last_login>,
 <django.db.models.fields.BooleanField: is_superuser>,
 <django.db.models.fields.CharField: username>,
 <django.db.models.fields.CharField: first_name>,
 <django.db.models.fields.CharField: last_name>,
 <django.db.models.fields.EmailField: email>,
 <django.db.models.fields.BooleanField: is_staff>,
 <django.db.models.fields.BooleanField: is_active>,
 <django.db.models.fields.DateTimeField: date_joined>,
 <django.db.models.fields.related.ManyToManyField: groups>,
 <django.db.models.fields.related.ManyToManyField: user_permissions>)

In [13]: [field.name for field in User._meta.get_fields()]
Out[13]:
['logentry',
 'id',
 'password',
 'last_login',
 'is_superuser',
 'username',
 'first_name',
 'last_name',
 'email',
 'is_staff',
 'is_active',
 'date_joined',
 'groups',
 'user_permissions']


元包含的模型字段在多个位置作为各自字段对象的列表列出。当关键字是字段名时,使用它们作为字典可能更容易。

在我看来,这是收集和组织模型字段对象最不相关和最具表现力的方法:

1
2
3
4
5
6
def get_model_fields(model):
  fields = {}
  options = model._meta
  for field in sorted(options.concrete_fields + options.many_to_many + options.virtual_fields):
    fields[field.name] = field
  return fields

(请参阅django.forms.models.fields中的示例用法,了解u model。)


这个怎么样。

1
fields = Model._meta.fields


根据Django文档2.2,您可以使用:

获取所有字段:Model._meta.get_fields()

获取单个字段:Model._meta.get_field('field name')

Session._meta.get_field('expire_date')


如果您的管理站点需要这样做,还有ModelAdmin.get_fields方法(docs),它返回字段名stringslist

例如:

1
2
3
4
5
6
7
class MyModelAdmin(admin.ModelAdmin):
    # extending change_view, just as an example
    def change_view(self, request, object_id=None, form_url='', extra_context=None):
        # get the model field names
        field_names = self.get_fields(request)
        # use the field names
        ...