Django获取Model字段顺序。

5
有没有一种方法可以按照代码顺序获取它们,或者为Django模型的字段设置顺序?当我调用MyModel._meta.get_fields()时,它们是无序的(尽管只要您不重置服务器,它似乎是相同的“无序”顺序)。
如果可能,而不必更改基本库或覆盖任何方法
我已经阅读了关于表单中排序的内容https://docs.djangoproject.com/en/1.9/ref/forms/api/#django.forms.Form.order_fields,但没有在模型本身中找到。
元属性'ordering'仅在进行查询时定义对象的默认排序。

@e4c5 我想知道文档中是否有任何内容允许我为_meta.get_fields()定义顺序。 - Mojimi
4个回答

6
实际上,get_fields() 按照固定顺序返回字段。
看一下 Django 的 示例:
>>> from django.contrib.auth.models import User
>>> User._meta.get_fields()
(<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>)

我已经重复了这段代码,并得到了相同的结果。如果你深入研究一下源代码,你会发现顺序如下:
  1. 每个parent字段以递归方式获取。
  2. 远程字段。
  3. 本地字段。
  4. 本地多对多字段。
  5. 私有字段。
这说明,如果您在模型中先定义了某些普通字段,那么您将始终在get_fields()结果中以相同的顺序获得它们。
但是要小心依赖未记录的行为,因为它可能在未来被更改而没有任何警告。

1
从我的测试来看,它们以相同的顺序出现,但不是特定的顺序。但是如果重新启动服务器,这个顺序会改变。 - Mojimi
1
你是正确的,我的错误是其他的问题,我把结果放在另一个字典中,导致它们无序。 - Mojimi

1
如果您想按照定义的顺序获取模型中定义的所有字段列表,则可以将以下类方法添加到您的模型定义中。 (或者将函数体移动到您想要的任何位置)
import itertools
from django.db.models.fields import Field

@classmethod
def getModelFields(cls):
    #Pulled this from djangos ModelForm source code
    sortable_private_fields = [f for f in cls._meta.private_fields if isinstance(f, Field)]
    return sorted(itertools.chain(cls._meta.concrete_fields, sortable_private_fields, cls._meta.many_to_many))

这是因为Django的Field定义了自定义的__eq____lt__方法,引用了内部的creation_counter。这使我们能够构建模型上所有字段的列表,并简单地使用sorted按顺序获取它们。 实际上,这就是ModelForm如何能够按定义顺序显示模型中所有字段的原理。

0

使用User._meta.fields按顺序获取模型字段。

    for e in User._meta.fields:
        t = e.get_internal_type()
        print(t, e.name)

-4

1
发生在我们中最好的人身上 ;) - whieronymus
1
实际上,我刚意识到这不是答案,这定义了查询对象的默认排序,而不是从_meta.get_fields()获取字段的顺序。 - Mojimi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接