我已经定义了一个User
类,它最终继承自models.Model
。我想获得为此模型定义的所有字段的列表。例如,phone_number = CharField(max_length=20)
。基本上,我想要检索从Field
类继承的任何内容。
我以为我可以利用inspect.getmembers(model)
检索这些内容,但它返回的列表不包含任何这些字段。看起来Django已经掌握了这个类,并添加了所有的魔法属性,并删除了实际定义的内容。那么......我怎样才能获得这些领域?它们可能具有为自己的内部目的检索它们的功能吗?
答案 0 :(得分:269)
您应该使用get_fields()
:
[f.name for f in MyModel._meta.get_fields()]
get_all_field_names()
方法为deprecated starting from Django
1.8 and will be removed in 1.10。
上面链接的文档页面提供了get_all_field_names()
的完全向后兼容的实现,但是对于大多数用途,前面的示例应该可以正常工作。
model._meta.get_all_field_names()
这应该可以解决问题。
这需要一个实际的模型实例。如果你拥有的只是django.db.models.Model
的子类,那么你应该调用myproject.myapp.models.MyModel._meta.get_all_field_names()
答案 1 :(得分:69)
此处提到的get_all_related_fields()
方法已deprecated in 1.8。从现在开始get_fields()
。
>> from django.contrib.auth.models import User
>> User._meta.get_fields()
答案 2 :(得分:52)
我发现将此添加到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
答案 3 :(得分:11)
这就是诀窍。我只在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
来获取它们。
答案 4 :(得分:10)
def __iter__(self):
field_names = [f.name for f in self._meta.fields]
for field_name in field_names:
value = getattr(self, field_name, None)
yield (field_name, value)
这在django==1.11.8
答案 5 :(得分:7)
MyModel._meta.get_all_field_names()
已弃用多个版本,Django 1.10中已移除。
以下是向后兼容的建议from the docs:
from itertools import chain
list(set(chain.from_iterable(
(field.name, field.attname) if hasattr(field, 'attname') else (field.name,)
for field in MyModel._meta.get_fields()
# For complete backwards compatibility, you may want to exclude
# GenericForeignKey from the results.
if not (field.many_to_one and field.related_model is None)
)))
答案 6 :(得分:6)
目前尚不清楚您是否有类的实例或类本身并尝试检索字段,但不管怎样,请考虑以下代码
使用实例
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'
答案 7 :(得分:6)
由于大多数答案已过时,因此我将尝试在 Django 2.2 上进行更新 在这里发布-您的应用(发布,博客,商店等)
1)通过模型链接:https://docs.djangoproject.com/en/2.2/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>...
和
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 = BlogPost._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 Organisation._meta.fields]
parent_fields = BlogPost.get_deferred_fields(BlogPost)
list_display = all_fields
read_only = parent_fields
答案 8 :(得分:5)
添加,我使用自我对象,这对我有用:
[f.name for f in self.model._meta.get_fields()]
答案 9 :(得分:4)
至少使用Django 1.9.9 - 我目前正在使用的版本 - ,请注意.get_fields()
实际上也是&#34;考虑&#34;任何外国模型作为一个领域,这可能是有问题的。说你有:
class Parent(models.Model):
id = UUIDField(primary_key=True)
class Child(models.Model):
parent = models.ForeignKey(Parent)
接着是
>>> map(lambda field:field.name, Parent._model._meta.get_fields())
['id', 'child']
while,如@Rockallite所示
>>> map(lambda field:field.name, Parent._model._meta.local_fields)
['id']
答案 10 :(得分:4)
因此,在我找到这篇文章之前,我已经成功地找到了它。
Model._meta.fields
与
相同Model._meta.get_fields()
我不确定结果是否有区别。我运行了此循环并获得了相同的输出。
for field in Model._meta.fields:
print(field.name)
答案 11 :(得分:0)
有时我们也需要db列:
def get_db_field_names(instance):
your_fields = instance._meta.local_fields
db_field_names=[f.name+'_id' if f.related_model is not None else f.name for f in your_fields]
model_field_names = [f.name for f in your_fields]
return db_field_names,model_field_names
调用方法以获取字段:
db_field_names,model_field_names=get_db_field_names(Mymodel)
答案 12 :(得分:-1)
为什么不仅仅使用它:
manage.py inspectdb
示例输出:
class GuardianUserobjectpermission(models.Model):
id = models.IntegerField(primary_key=True) # AutoField?
object_pk = models.CharField(max_length=255)
content_type = models.ForeignKey(DjangoContentType, models.DO_NOTHING)
permission = models.ForeignKey(AuthPermission, models.DO_NOTHING)
user = models.ForeignKey(CustomUsers, models.DO_NOTHING)
class Meta:
managed = False
db_table = 'guardian_userobjectpermission'
unique_together = (('user', 'permission', 'object_pk'),)