Joe*_*e J 107 django introspection django-models metamodel
给定一个Django模型,我试图列出它的所有字段.我已经看到了一些使用_meta模型属性执行此操作的示例,但是meta前面的下划线是否表示_meta属性是私有属性,不应该直接访问?...例如,因为_meta的布局将来可能会改变而不是一个稳定的API?
_meta是这个规则的例外吗?它是否稳定并且可以使用,或者它被认为是不好的做法?或者是否有函数或其他方法来反省模型的字段而不使用_meta属性?下面是一些链接的列表,显示了如何使用_meta属性执行此操作
任何建议都非常感谢.
Wil*_*rdy 135
_meta是私人的,但相对稳定.正在努力将其正式化,记录并删除可能在1.3或1.4之前发生的下划线.我想会努力确保事情向后兼容,因为很多人一直在使用它.
如果您特别关注兼容性,请编写一个接受模型并返回字段的函数.这意味着如果将来某些事情发生变化,您只需要更改一个功能.
def get_model_fields(model):
return model._meta.fields
Run Code Online (Sandbox Code Playgroud)
我相信这会返回一个Field对象列表.要从实例中获取每个字段的值,请使用getattr(instance, field.name).
更新:Django贡献者正在开发一个API来替换_Meta对象,作为Google Summer of Code的一部分.请参阅:
- https://groups.google.com/forum/#!topic/django-developers/hD4roZq0wyk
- https://code.djangoproject.com/wiki/new_meta_api
Pir*_*sB3 87
我知道这个职位是很老,但我只在乎告诉任何人谁是寻找有一个公众和官方的API做这同样的事情:get_fields()和get_field()
用法:
fields = model._meta.get_fields()
my_field = model._meta.get_field('my_field')
Run Code Online (Sandbox Code Playgroud)
https://docs.djangoproject.com/en/1.8/ref/models/meta/
这是Django在从模型构建表单时所做的事情.它使用的是_meta属性,但正如Bernhard所说,它同时使用了_meta.fields和_meta.many_to_many.看看django.forms.models.fields_for_model,你可以这样做:
opts = model._meta
for f in sorted(opts.fields + opts.many_to_many):
print '%s: %s' % (f.name, f)
Run Code Online (Sandbox Code Playgroud)
_meta 包含的模型字段作为相应字段对象的列表列在多个位置。将它们作为字典使用可能更容易,其中键是字段名称。
在我看来,这是收集和组织模型字段对象的最多余且最具表现力的方式:
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
Run Code Online (Sandbox Code Playgroud)
(请参阅django.forms.models.fields_for_model 中的此示例用法。)
现在有一个特殊的方法 - get_fields()
>>> from django.contrib.auth.models import User
>>> User._meta.get_fields()
Run Code Online (Sandbox Code Playgroud)
它接受两个可用于控制返回哪些字段的参数:
include_parents
默认为True.递归地包括在父类上定义的字段.如果设置为False,则get_fields()将仅搜索直接在当前模型上声明的字段.直接从抽象模型或代理类继承的模型中的字段被视为本地字段,而不是父项.
include_hidden
默认为False.如果设置为True,则get_fields()将包含用于支持其他字段功能的字段.这还将包括具有以"+"开头的related_name(例如ManyToManyField或ForeignKey)的任何字段
get_fields()返回一个tuple,每个元素都是一个Model field类型,不能直接用作字符串。因此,field.name将返回字段名称
my_model_fields = [field.name for field in MyModel._meta.get_fields()]
上面的代码将返回一个列表conatining所有字段名称
示例
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']
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
94649 次 |
| 最近记录: |