我已经定义了一个User类,它(最终)继承自models.Model。我想获得为这个模型定义的所有字段的列表。例如,phone_number = CharField(max_length=20)。基本上,我想检索从Field类继承的任何东西。

我认为我可以利用inspect.getmembers(model)来检索这些字段,但是它返回的列表不包含这些字段中的任何一个。看起来Django已经掌握了这个类,添加了它所有神奇的属性,并去掉了实际定义的内容。所以…我怎样才能得到这些田地?他们可能有一个功能来检索他们自己的内部目的?


当前回答

由于大多数答案都过时了,我将尝试更新Django 2.2 这里帖子-你的应用程序(帖子,博客,商店等)

1)从模型链接:https://docs.djangoproject.com/en/stable/ref/models/meta/

from posts.model import BlogPost

all_fields = BlogPost._meta.fields
#or
all_fields = BlogPost._meta.get_fields()

注意:

all_fields=BlogPost._meta.get_fields()

也会得到一些关系,例如:你不能在视图中显示。 以我为例:

Organisation._meta.fields
(<django.db.models.fields.AutoField: id>, <django.db.models.fields.DateField: created>...

and

Organisation._meta.get_fields()
(<ManyToOneRel: crm.activity>, <django.db.models.fields.AutoField: id>, <django.db.models.fields.DateField: created>...

2)事例

from posts.model import BlogPost

bp = BlogPost()
all_fields = bp._meta.fields

3)父母模式

假设我们将Post作为父模型,并且希望在列表中查看所有字段,并且在Edit模式中将父字段设置为只读。

from django.contrib import admin
from posts.model import BlogPost 

@admin.register(BlogPost)
class BlogPost(admin.ModelAdmin):
    all_fields = [f.name for f in Organisation._meta.fields]
    parent_fields = BlogPost.get_deferred_fields(BlogPost)

    list_display = all_fields
    read_only = parent_fields

其他回答

不清楚您拥有的是类的实例还是类本身,并试图检索字段,但无论哪种方式,考虑以下代码

使用实例

instance = User.objects.get(username="foo")
instance.__dict__ # returns a dictionary with all fields and their values
instance.__dict__.keys() # returns a dictionary with all fields
list(instance.__dict__.keys()) # returns list with all fields

使用类

User._meta.__dict__.get("fields") # returns the fields

# to get the field names consider looping over the fields and calling __str__()
for field in User._meta.__dict__.get("fields"):
    field.__str__() # e.g. 'auth.User.id'

Django 1.8及以上版本:

你应该使用get_fields():

[f.name for f in MyModel._meta.get_fields()]

从Django开始不建议使用get_all_field_names()方法 将在1.10中删除。

上面链接的文档页面提供了完全向后兼容的get_all_field_names()实现,但是对于大多数目的,前面的示例应该可以正常工作。


1.8之前的Django版本:

model._meta.get_all_field_names()

这样应该可以了。

这需要一个实际的模型实例。如果你只有django.db.models的一个子类。然后你应该调用myproject.myapp.models.MyModel._meta.get_all_field_names()

由于大多数答案都过时了,我将尝试更新Django 2.2 这里帖子-你的应用程序(帖子,博客,商店等)

1)从模型链接:https://docs.djangoproject.com/en/stable/ref/models/meta/

from posts.model import BlogPost

all_fields = BlogPost._meta.fields
#or
all_fields = BlogPost._meta.get_fields()

注意:

all_fields=BlogPost._meta.get_fields()

也会得到一些关系,例如:你不能在视图中显示。 以我为例:

Organisation._meta.fields
(<django.db.models.fields.AutoField: id>, <django.db.models.fields.DateField: created>...

and

Organisation._meta.get_fields()
(<ManyToOneRel: crm.activity>, <django.db.models.fields.AutoField: id>, <django.db.models.fields.DateField: created>...

2)事例

from posts.model import BlogPost

bp = BlogPost()
all_fields = bp._meta.fields

3)父母模式

假设我们将Post作为父模型,并且希望在列表中查看所有字段,并且在Edit模式中将父字段设置为只读。

from django.contrib import admin
from posts.model import BlogPost 

@admin.register(BlogPost)
class BlogPost(admin.ModelAdmin):
    all_fields = [f.name for f in Organisation._meta.fields]
    parent_fields = BlogPost.get_deferred_fields(BlogPost)

    list_display = all_fields
    read_only = parent_fields

我发现把这个添加到django模型中非常有用:

def __iter__(self):
    for field_name in self._meta.get_all_field_names():
        value = getattr(self, field_name, None)
        yield (field_name, value)

这让你做:

for field, val in object:
    print field, val

这很管用。我只在Django 1.7中测试它。

your_fields = YourModel._meta.local_fields
your_field_names = [f.name for f in your_fields]

Model._meta。Local_fields不包含多对多字段。您应该使用Model._meta.local_many_to_many来获取它们。