我想在我的django应用程序中为每个模型添加几个字段 . 这次是 created_at
, updated_at
和 notes
. 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 ...
它按预期工作,但我想知道,有没有更好的方法来实现我的目标?
3 回答
如果你主要需要订购Django 's admin you could also create your 2832828 -admin class via sub-classing Django'的管理类 . 有关自定义管理中字段的显示,请参阅http://docs.djangoproject.com/en/dev/intro/tutorial02/#customize-the-admin-form . 您可以根据需要覆盖管理员
__init__
以在创建管理实例时设置字段/字段集 . 例如 . 你可以这样做:除此之外,我认为修改(私人)
_field_name_cache
不是一个好习惯!我遇到了同样的问题,但我发现这些解决方案存在问题,所以这就是我所做的:
与更改模型中的字段相比,更改管理员中的字段集对我来说更有意义 .
我也不喜欢其他解决方案,所以我只是直接修改了迁移文件 .
每当你在models.py中创建一个新表时,你将不得不运行"python manage.py makemigrations"(我相信这在Django> = v1.7.5) . 执行此操作后,在your_app_path / migrations /目录中打开新创建的迁移文件,然后只需将行移动到您希望它们所在的顺序 . 然后运行"python manage.py migrate" . 瞧!通过进入"python manage.py dbshell",您可以看到列的顺序正是您想要的!
此方法的缺点:您必须为您创建的每个表手动执行此操作,但幸运的是,开销很小 . 这只能在您创建新表时进行,而不是修改现有表 .