如何获取 Django 模型的所有字段?

发布于 2024-09-17 11:51:10 字数 831 浏览 5 评论 0原文

给定一个 Django 模型,我试图列出它的所有字段。我见过一些使用 _meta 模型属性执行此操作的示例,但是 meta 前面的下划线是否表明 _meta 属性是私有属性,不应直接访问? ...因为,例如,_meta 的布局将来可能会发生变化,并且不是一个稳定的 API?

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

。非常感谢任何建议。

django 对象获取/设置字段

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

如何内省 django 模型字段?

Given a Django model, I'm trying to list all of its fields. I've seen some examples of doing this using the _meta model attribute, but doesn't the underscore in front of meta indicate that the _meta attribute is a private attribute and shouldn't be accessed directly? ... Because, for example, the layout of _meta could change in the future and not be a stable API?

Is _meta an exception to this rule? Is it stable and ready to use or is it considered bad practice to access it? Or is there a function or some other way to introspect the fields of a model without using the _meta attribute? Below is a list of some links showing how to do this using the _meta attribute

Any advice is much appreciated.

django object get/set field

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

How to introspect django model fields?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(13

懒的傷心 2024-09-24 11:51:10

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

如果您特别关心兼容性,请编写一个接受模型并返回字段的函数。这意味着如果将来某些事情发生变化,您只需更改一项功能即可。

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

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

更新:作为 Google Summer of Code 的一部分,Django 贡献者正在开发一个 API 来替换 _Meta 对象。请参阅:
- https://groups.google.com/forum/#!topic/ django-developers/hD4roZq0wyk
- https://code.djangoproject.com/wiki/new_meta_api

_meta is private, but it's relatively stable. There are efforts to formalise it, document it and remove the underscore, which might happen before 1.3 or 1.4. I imagine effort will be made to ensure things are backwards compatible, because lots of people have been using it anyway.

If you're particularly concerned about compatibility, write a function that takes a model and returns the fields. This means if something does change in the future, you only have to change one function.

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

I believe this will return a list of Field objects. To get the value of each field from the instance, use getattr(instance, field.name).

Update: Django contributors are working on an API to replace the _Meta object as part of a Google Summer of Code. See:
- https://groups.google.com/forum/#!topic/django-developers/hD4roZq0wyk
- https://code.djangoproject.com/wiki/new_meta_api

各空 2024-09-24 11:51:10

我知道这篇文章已经很老了,但我只是想告诉任何正在搜索相同内容的人,有一个公共和官方 API 可以执行此操作:get_fields()get_field( )

用法:

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

https://docs.djangoproject.com/en/3.2/ref/models/meta/#retriving-all-field-instances-of-a-model

I know this post is pretty old, but I just cared to tell anyone who is searching for the same thing that there is a public and official API to do this: get_fields() and get_field()

Usage:

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

https://docs.djangoproject.com/en/3.2/ref/models/meta/#retrieving-all-field-instances-of-a-model

眼眸里的快感 2024-09-24 11:51:10

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

my_model_fields = [field.name for field in MyModel._meta.get_fields()]
上面的代码将返回一个包含所有字段名称的列表

示例

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']

get_fields() returns a tuple and each element is a Model field type, which can't be used directly as a string. So, field.name will return the field name

my_model_fields = [field.name for field in MyModel._meta.get_fields()]
The above code will return a list containing all field names

Example

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']
一指流沙 2024-09-24 11:51:10

现在有特殊方法 - get_fields()

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

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

  • include_parents

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

  • include_hidden

    默认为假。如果设置为 True,get_fields() 将包含用于支持其他字段功能的字段。这还包括任何具有以“+”开头的 related_name 的字段(例如 ManyToManyField 或foreignKey),

Now there is special method - get_fields()

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

It accepts two parameters that can be used to control which fields are returned:

  • include_parents

    True by default. Recursively includes fields defined on parent classes. If set to False, get_fields() will only search for fields declared directly on the current model. Fields from models that directly inherit from abstract models or proxy classes are considered to be local, not on the parent.

  • include_hidden

    False by default. If set to True, get_fields() will include fields that are used to back other field’s functionality. This will also include any fields that have a related_name (such as ManyToManyField, or ForeignKey) that start with a “+”

无远思近则忧 2024-09-24 11:51:10

fields = [f"{f.name}_id" if f.is_relation else f.name for f in model._meta.fields]

fields = [f"{f.name}_id" if f.is_relation else f.name for f in model._meta.fields]

躲猫猫 2024-09-24 11:51:10

这是 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)

This is something that is done by Django itself when building a form from a model. It is using the _meta attribute, but as Bernhard noted, it uses both _meta.fields and _meta.many_to_many. Looking at django.forms.models.fields_for_model, this is how you could do it:

opts = model._meta
for f in sorted(opts.fields + opts.many_to_many):
    print '%s: %s' % (f.name, f)
趁年轻赶紧闹 2024-09-24 11:51:10

_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

参见此示例用法在 django.forms.models.fields_for_model 中。)

The model fields contained by _meta are listed in multiple locations as lists of the respective field objects. It may be easier to work with them as a dictionary where the keys are the field names.

In my opinion, this is most irredundant and expressive way to collect and organize the model field objects:

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

(See This example usage in django.forms.models.fields_for_model.)

被你宠の有点坏 2024-09-24 11:51:10

这个怎么样呢。

fields = Model._meta.fields

How about this one.

fields = Model._meta.fields
风柔一江水 2024-09-24 11:51:10

如果您的管理站点需要此功能,还有ModelAdmin.get_fields方法(docs),它返回字段名称字符串的列表

例如:

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
        ...

If you need this for your admin site, there is also the ModelAdmin.get_fields method (docs), which returns a list of field name strings.

For example:

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
        ...
℉絮湮 2024-09-24 11:51:10

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

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

要获取单个字段: Model._meta.get_field('field name')< /代码>

例如。 Session._meta.get_field('expire_date')

As per the django documentation 2.2 you can use:

To get all fields: Model._meta.get_fields()

To get an individual field: Model._meta.get_field('field name')

ex. Session._meta.get_field('expire_date')

浪推晚风 2024-09-24 11:51:10

instance._meta.get_fields() 返回 Django 模型中所有字段(即列)的列表。

此方法用于内省模型的字段、它们的类型以及它们与其他模型的关系。该方法返回 Field 对象的列表,这些对象表示模型中的各个字段。

例如,假设您有一个名为 MyModel 的 Django 模型。您可以使用 instance._meta.get_fields() 获取模型中所有字段的列表:

from myapp.models import MyModel

my_instance = MyModel.objects.get(id=1)
fields = my_instance._meta.get_fields()

fields 变量现在将包含 MyModel 中所有字段的列表> 模型,包括 idnamecreated_at 等字段以及任何相关字段(例如外键 )。您可以使用此列表来访问和操作模型中的各个字段。

instance._meta.get_fields() returns a list of all the fields (i.e. columns) in a Django model.

This method is used to introspect the model's fields, their types, and their relationships with other models. The method returns a list of Field objects, which represent the individual fields in the model.

For example, suppose you have a Django model called MyModel. You can use instance._meta.get_fields() to get a list of all the fields in the model:

from myapp.models import MyModel

my_instance = MyModel.objects.get(id=1)
fields = my_instance._meta.get_fields()

The fields variable will now contain a list of all the fields in the MyModel model, including fields such as id, name, created_at, and any related fields (such as foreign keys). You can use this list to access and manipulate the individual fields in the model.

黑寡妇 2024-09-24 11:51:10

为了以简洁易读的方式获取所有字段,您可以使用“model_to_dict”将它们收集到字典中:

from django.forms.models import model_to_dict

my_object = ModelName.objects.get(id=1) 
data_dict = model_to_dict(my_instance)
print(data_dict)

To get all fields in a concise and readable manner you can use "model_to_dict" to collect them into a dictionary:

from django.forms.models import model_to_dict

my_object = ModelName.objects.get(id=1) 
data_dict = model_to_dict(my_instance)
print(data_dict)
毁虫ゝ 2024-09-24 11:51:10

另一种方法是将函数添加到模型中,当您想要覆盖日期时,可以调用该函数。

class MyModel(models.Model):
    name = models.CharField(max_length=256)
    created = models.DateTimeField(auto_now_add=True)
    modified = models.DateTimeField(auto_now=True)

    def set_created_date(self, created_date):
        field = self._meta.get_field('created')
        field.auto_now_add = False
        self.created = created_date

    def set_modified_date(self, modified_date):
        field = self._meta.get_field('modified')
        field.auto_now = False
        self.modified = modified_date

my_model = MyModel(name='test')
my_model.set_modified_date(new_date)
my_model.set_created_date(new_date)
my_model.save()

Another way is add functions to the model and when you want to override the date you can call the function.

class MyModel(models.Model):
    name = models.CharField(max_length=256)
    created = models.DateTimeField(auto_now_add=True)
    modified = models.DateTimeField(auto_now=True)

    def set_created_date(self, created_date):
        field = self._meta.get_field('created')
        field.auto_now_add = False
        self.created = created_date

    def set_modified_date(self, modified_date):
        field = self._meta.get_field('modified')
        field.auto_now = False
        self.modified = modified_date

my_model = MyModel(name='test')
my_model.set_modified_date(new_date)
my_model.set_created_date(new_date)
my_model.save()
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文