Django按顺序获取模型字段

时间:2016-12-20 19:04:45

标签: django django-models

有没有办法按代码顺序获取它们,或者为Django模型的字段设置顺序?当我打电话给MyModel._meta.get_fields()时,它们会无序(只要您没有重置服务器,就会发出相同的'无序'顺序)。

如果可能的话,无需更改覆盖任何方法的基础库

我读过关于表单https://docs.djangoproject.com/en/1.9/ref/forms/api/#django.forms.Form.order_fields的排序,但不是模型本身的排序

元属性'ordering'仅在定义查询时定义对象的默认排序

4 个答案:

答案 0 :(得分:3)

实际上get_fields()会以固定顺序返回字段。

看看django example

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

我重复了这段代码并获得了相同的结果。 如果您更深入地查看sources,您会发现订单如下:

  1. 以递归方式获取每个parent字段。
  2. 远程字段。
  3. 本地字段。
  4. 本地多对多字段。
  5. 私人领域。
  6. 所有这一切都表明,如果你在模型中的某个其他平凡字段之前定义一些简单的字段,那么你总是会在get_fields()结果中以相同的顺序得到它。

    但要小心依赖未记录的行为,以便将来可以在没有任何警告的情况下进行更改。

答案 1 :(得分:1)

使用User._meta.fields依次获取模型字段。

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

答案 2 :(得分:0)

如果要获取模型中定义的所有字段的列表,无论它们是否为M2M字段,都可以执行以下操作:

import itertools
from django.db.models.fields import Field as ModelField

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

尝试这样做的时间超过我想承认的时间之后,我意识到,如果您制作了模型表单,则字段始终处于正确的顺序,因此它们必须在其中某个地方存在一些隐藏的魔术。我浏览了源代码,发现说魔术。对我来说很完美。

答案 3 :(得分:-3)

只需添加&#39;订购&#39;到Meta类:

class Model(models.Model):
    slug = models.SlugField()
    name = models.CharField(max_length=30)
    other_field = models.TextField(blank=True, null=True)


    class Meta:
        ordering = ('name',)

https://docs.djangoproject.com/en/1.10/ref/models/options/#ordering