问题描述
我想在django应用程序中为每个模型添加几个字段。这次是 created_at
, updated_at
和笔记
。每个20多个机型的重复代码看起来很笨。所以,我决定使用抽象基类来添加这些字段。问题是从抽象基类继承的字段首先出现在管理员的字段列表中。声明每个ModelAdmin类的字段顺序不是一个选项,它比手动字段声明更复杂的代码。 在我的最终解决方案中,我修改了模型构造函数来重新排序字段在_meta之前创建新的实例:
class MyModel(models.Model):
#服务字段
note = 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 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,** kwa rgs)
class ModelA(MyModel):
field1 = models.CharField()
field2 = models.CharField()
#etc ...
它的工作原理,但我想知道,有没有更好的方法来实现我的目标? >
如果您主要需要Django管理员的订购,您还可以通过Django的管理员类的子类创建通用-admin类。请参阅,用于自定义管理员中字段的显示。
您可以根据需要覆盖管理员的 __ init __
,以便在创建管理实例时设置字段/字段。例如。您可以执行以下操作:
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)
此外,我认为修改(私人) _field_name_cache
!
不是一个好习惯
I want to add few fields to every model in my django application. This time it's created_at
, updated_at
and notes
. Duplicating code for every of 20+ models seems dumb. So, I decided to use abstract base class which would add these fields. The problem is that fields inherited from abstract base class come first in the field list in admin. Declaring field order for every ModelAdmin class is not an option, it's even more duplicate code than with manual field declaration.
In my final solution, I modified model constructor to reorder fields in _meta before creating new instance:
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 ...
It works as intended, but I'm wondering, is there a better way to acheive my goal?
If you mainly need the ordering for Django's admin you could also create your "generic"-admin class via sub-classing Django's admin class. See http://docs.djangoproject.com/en/dev/intro/tutorial02/#customize-the-admin-form for customizing the display of fields in the admin.You could overwrite the admin's __init__
to setup fields/fieldsets on creation of the admin instance as you wish. E.g. you could do something like:
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)
Besides that i think it's not a good practice to modify the (private) _field_name_cache
!
这篇关于在Django模型中重新排序字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!