mpe*_*pen 172 django django-models
我已经定义了一个User(最终)继承自的类models.Model.我想获得为此模型定义的所有字段的列表.例如,phone_number = CharField(max_length=20).基本上,我想要检索从Field类继承的任何东西.
我以为我可以通过利用来检索这些inspect.getmembers(model),但它返回的列表不包含任何这些字段.看起来Django已经掌握了这个类,并添加了所有的魔法属性,并删除了实际定义的内容.那么......我怎样才能获得这些领域?它们可能具有为自己的内部目的检索它们的功能吗?
ros*_*dia 280
对于Django 1.8及更高版本:
该get_fields()方法从Django 1.8开始不推荐使用,将在1.10中删除.
上面链接的文档页面提供了完全向后兼容的实现get_all_field_names(),但是对于大多数用途get_all_field_names()应该可以正常工作.
对于1.8之前的Django版本:
[f.name for f in MyModel._meta.get_fields()]
Run Code Online (Sandbox Code Playgroud)
这应该够了吧.
这需要一个实际的模型实例.如果您拥有的是子类django.db.models.Model,那么您应该调用myproject.myapp.models.MyModel._meta.get_all_field_names()
Wil*_*Wil 72
get_all_related_fields()此处提到的方法已在1.8中弃用.从现在开始吧get_fields().
>> from django.contrib.auth.models import User
>> User._meta.get_fields()
Run Code Online (Sandbox Code Playgroud)
bjw*_*bjw 53
我发现将这个添加到django模型非常有帮助:
def __iter__(self):
for field_name in self._meta.get_all_field_names():
value = getattr(self, field_name, None)
yield (field_name, value)
Run Code Online (Sandbox Code Playgroud)
这可以让你做到:
for field, val in object:
print field, val
Run Code Online (Sandbox Code Playgroud)
Mak*_*ks 19
由于大多数答案已过时,因此我将尝试在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()
Run Code Online (Sandbox Code Playgroud)
注意:
all_fields=BlogPost._meta.get_fields()
Run Code Online (Sandbox Code Playgroud)
也将获得一些关系,例如。您无法在视图中显示。
就我而言:
Organisation._meta.fields
(<django.db.models.fields.AutoField: id>, <django.db.models.fields.DateField: created>...
Run Code Online (Sandbox Code Playgroud)
和
Organisation._meta.get_fields()
(<ManyToOneRel: crm.activity>, <django.db.models.fields.AutoField: id>, <django.db.models.fields.DateField: created>...
Run Code Online (Sandbox Code Playgroud)
2)从实例
from posts.model import BlogPost
bp = BlogPost()
all_fields = BlogPost._meta.fields
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
Ans*_*uez 14
一个别人没有提到的细节:
[f.name for f in MyModel._meta.get_fields()]
Run Code Online (Sandbox Code Playgroud)
得到,例如
['id', 'name', 'occupation']
Run Code Online (Sandbox Code Playgroud)
和
[f.get_attname() for f in MyModel._meta.get_fields()]
Run Code Online (Sandbox Code Playgroud)
得到
['id', 'name', 'occupation_id']
Run Code Online (Sandbox Code Playgroud)
如果
reg = MyModel.objects.first()
Run Code Online (Sandbox Code Playgroud)
然后
reg.occupation
Run Code Online (Sandbox Code Playgroud)
得到,例如
<Occupation: Dev>
Run Code Online (Sandbox Code Playgroud)
和
reg.occupation_id
Run Code Online (Sandbox Code Playgroud)
得到
1
Run Code Online (Sandbox Code Playgroud)
Roc*_*ite 12
这样就可以了.我只在Django 1.7中测试它.
your_fields = YourModel._meta.local_fields
your_field_names = [f.name for f in your_fields]
Run Code Online (Sandbox Code Playgroud)
Model._meta.local_fields不包含多对多字段.你应该使用它们Model._meta.local_many_to_many.
Viv*_*and 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)
Run Code Online (Sandbox Code Playgroud)
这对我有用 django==1.11.8
MyModel._meta.get_all_field_names()在Django 1.10中被弃用了几个版本并删除了.
以下是来自文档的向后兼容建议:
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)
)))
Run Code Online (Sandbox Code Playgroud)
目前尚不清楚您是否具有该类的实例或该类本身,并尝试检索字段,但是无论哪种方式,请考虑以下代码
使用实例
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
Run Code Online (Sandbox Code Playgroud)
使用课程
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'
Run Code Online (Sandbox Code Playgroud)
至少对于Django 1.9.9——我目前使用的版本——请注意,.get_fields()实际上它也“考虑”了任何外国模型作为一个字段,这可能是有问题的。说你有:
class Parent(models.Model):
id = UUIDField(primary_key=True)
class Child(models.Model):
parent = models.ForeignKey(Parent)
Run Code Online (Sandbox Code Playgroud)
它遵循
>>> map(lambda field:field.name, Parent._model._meta.get_fields())
['id', 'child']
Run Code Online (Sandbox Code Playgroud)
同时,如@Rockallite 所示
>>> map(lambda field:field.name, Parent._model._meta.local_fields)
['id']
Run Code Online (Sandbox Code Playgroud)
补充一点,我正在使用自我对象,这对我有用:
[f.name for f in self.model._meta.get_fields()]
Run Code Online (Sandbox Code Playgroud)
所以在我找到这篇文章之前,我成功地发现它可以工作。
Model._meta.fields
Run Code Online (Sandbox Code Playgroud)
它同样有效
Model._meta.get_fields()
Run Code Online (Sandbox Code Playgroud)
我不确定结果有什么不同,如果有的话。我运行了这个循环并得到了相同的输出。
for field in Model._meta.fields:
print(field.name)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
132728 次 |
| 最近记录: |