Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Django模型中字段的重新排序_Python_Django_Django Models - Fatal编程技术网

Python Django模型中字段的重新排序

Python Django模型中字段的重新排序,python,django,django-models,Python,Django,Django Models,我想为django应用程序中的每个模型添加几个字段。这次它是在创建的,在更新的,注释。为20多个模型中的每一个复制代码似乎都很愚蠢。所以,我决定使用抽象基类来添加这些字段。问题是从抽象基类继承的字段在admin的字段列表中排在第一位。为每个ModelAdmin类声明字段顺序不是一个选项,它甚至比手动字段声明更重复 在我的最终解决方案中,我修改了模型构造函数,以便在创建新实例之前对_meta中的字段重新排序: class MyModel(models.Model): # Service f

我想为django应用程序中的每个模型添加几个字段。这次它是在创建的,在更新的,
注释
。为20多个模型中的每一个复制代码似乎都很愚蠢。所以,我决定使用抽象基类来添加这些字段。问题是从抽象基类继承的字段在admin的字段列表中排在第一位。为每个ModelAdmin类声明字段顺序不是一个选项,它甚至比手动字段声明更重复

在我的最终解决方案中,我修改了模型构造函数,以便在创建新实例之前对_meta中的字段重新排序:

class MyModel(models.Model):
    # Service fields
    notes = my_fields.NotesField()
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        abstract = True

    last_fields = ("notes", "created_at", "updated_at")
    def __init__(self, *args, **kwargs):
        new_order = [f.name for f in self._meta.fields]
        for field in self.last_fields:
            new_order.remove(field)
            new_order.append(field)
        self._meta._field_name_cache.sort(key=lambda x: new_order.index(x.name))
        super(MyModel, self).__init__(*args, **kwargs)

class ModelA(MyModel):
    field1 = models.CharField()
    field2 = models.CharField()
    #etc ... 

它按预期工作,但我想知道,有没有更好的方法来实现我的目标?

如果您主要需要Django的admin类的排序,您还可以通过对Django的admin类进行子分类来创建“泛型”admin类。有关自定义管理中字段显示的信息,请参见。 在创建管理员实例时,您可以根据需要覆盖管理员的
\uuuuu init\uuuu
,以设置字段/字段集。例如,你可以做如下事情:

class MyAdmin(admin.ModelAdmin):
    def __init__(self, model, admin_site):
        general_fields = ['notes', 'created_at', 'updated_at']
        fields = [f.name for f in self.model._meta.fields if f.name not in general_fields]
        self.fields = fields + general_fields
        super(admin.ModelAdmin, self).__init__(model, admin_site)

除此之外,我认为修改(私有)
\u字段\u名称\u缓存
不是一个好的做法

我遇到了同样的问题,但我发现这些解决方案存在问题,所以我做了以下几点:

class BaseAdmin(admin.ModelAdmin):
    def get_fieldsets(self, request, obj = None):
        res = super(BaseAdmin, self).get_fieldsets(request, obj)
        # I only need to move one field; change the following
        # line to account for more.
        res[0][1]['fields'].append(res[0][1]['fields'].pop(0))
        return res

对我来说,在管理中更改字段集比在模型中更改字段更有意义。

我也不喜欢其他解决方案,所以我只是直接修改了迁移文件

无论何时在models.py中创建新表,都必须运行“python manage.py makemigrations”(我相信Django>=v1.7.5)。完成此操作后,在您的_app_path/migrations/目录中打开新创建的迁移文件,只需按您希望的顺序移动行即可。然后运行“python manage.py migrate”。瞧!通过进入“python manage.py dbshell”,您可以看到列的顺序正是您想要的

这种方法的缺点是:必须为创建的每个表手动执行此操作,但幸运的是,开销很小。这只能在创建新表时完成,而不能修改现有表