Django 条件管理员 list_editable
Django conditional admin list_editable
有没有办法让 list_editable 在每个对象的基础上可选?例如 readonly fields 属性有这个选项,它不影响 changelist_view.
class MyAdmin(admin.ModelAdmin):
readonly_fields = ('foo',)
def get_readonly_fields(self, request, obj=None):
fields = super(MyAdmin, self).get_readonly_fields(request, obj=obj)
if obj.status == 'CLOSED':
return fields + ('bar',)
return fields
list_display 和其他一些属性也可以实现同样的效果。好像没有方法'get_list_editable_fields'。
我显然希望某些行是不可变的,但除了引发粗俗的错误之外似乎不起作用。我也没有找到有关该属性的任何文档
是否可以通过 list_display getter 以某种方式呈现小部件?
class MyAdmin(admin.ModelAdmin):
list_display = ('get_bar',)
list_editable = ('get_bar',)
def get_bar(self, obj):
return widget or str(obj.bar) # ???
get_bar.allow_tags = True
根据 Alasdair 的反馈进行更新:
def get_changelist_formset(self, request, **kwargs):
"""
Returns a FormSet class for use on the changelist page if list_editable
is used.
"""
# I run through this code for each row in the changelist, but there's nothing in kwargs, so I don't know how to use the instance as a guide to which fields should be in list_editable?
defaults = {
"formfield_callback": partial(self.formfield_for_dbfield, request=request),
}
defaults.update(kwargs)
return modelformset_factory(
self.model, self.get_changelist_form(request), extra=0,
fields=self.list_editable, **defaults
)
正如你所说,没有get_list_editable
方法。
尝试覆盖 get_changelist_formset
方法。我认为您需要复制整个方法,并更改传递给 modelformset_factory
.
的字段列表
此外,您可以覆盖 changelist_view
并执行类似的操作:
def changelist_view(self, request, extra_context=None):
resp = super(CustomModelAdmin, self).changelist_view(request, extra_context)
if something:
resp.context_data['cl'].formset = None
return resp
如前所述,ModelAdmin
class中没有get_list_editable
方法,但可以很容易地实现(在django==2.1
上测试):
class MyAdminClass(admin.ModelAdmin):
def get_list_editable(self, request):
"""
get_list_editable method implementation,
django ModelAdmin doesn't provide it.
"""
dynamically_editable_fields = ('name', 'published', )
return dynamically_editable_fields
def get_changelist_instance(self, request):
"""
override admin method and list_editable property value
with values returned by our custom method implementation.
"""
self.list_editable = self.get_list_editable(request)
return super(MyAdminClass, self).get_changelist_instance(request)
有没有办法让 list_editable 在每个对象的基础上可选?例如 readonly fields 属性有这个选项,它不影响 changelist_view.
class MyAdmin(admin.ModelAdmin):
readonly_fields = ('foo',)
def get_readonly_fields(self, request, obj=None):
fields = super(MyAdmin, self).get_readonly_fields(request, obj=obj)
if obj.status == 'CLOSED':
return fields + ('bar',)
return fields
list_display 和其他一些属性也可以实现同样的效果。好像没有方法'get_list_editable_fields'。
我显然希望某些行是不可变的,但除了引发粗俗的错误之外似乎不起作用。我也没有找到有关该属性的任何文档
是否可以通过 list_display getter 以某种方式呈现小部件?
class MyAdmin(admin.ModelAdmin):
list_display = ('get_bar',)
list_editable = ('get_bar',)
def get_bar(self, obj):
return widget or str(obj.bar) # ???
get_bar.allow_tags = True
根据 Alasdair 的反馈进行更新:
def get_changelist_formset(self, request, **kwargs):
"""
Returns a FormSet class for use on the changelist page if list_editable
is used.
"""
# I run through this code for each row in the changelist, but there's nothing in kwargs, so I don't know how to use the instance as a guide to which fields should be in list_editable?
defaults = {
"formfield_callback": partial(self.formfield_for_dbfield, request=request),
}
defaults.update(kwargs)
return modelformset_factory(
self.model, self.get_changelist_form(request), extra=0,
fields=self.list_editable, **defaults
)
正如你所说,没有get_list_editable
方法。
尝试覆盖 get_changelist_formset
方法。我认为您需要复制整个方法,并更改传递给 modelformset_factory
.
此外,您可以覆盖 changelist_view
并执行类似的操作:
def changelist_view(self, request, extra_context=None):
resp = super(CustomModelAdmin, self).changelist_view(request, extra_context)
if something:
resp.context_data['cl'].formset = None
return resp
如前所述,ModelAdmin
class中没有get_list_editable
方法,但可以很容易地实现(在django==2.1
上测试):
class MyAdminClass(admin.ModelAdmin):
def get_list_editable(self, request):
"""
get_list_editable method implementation,
django ModelAdmin doesn't provide it.
"""
dynamically_editable_fields = ('name', 'published', )
return dynamically_editable_fields
def get_changelist_instance(self, request):
"""
override admin method and list_editable property value
with values returned by our custom method implementation.
"""
self.list_editable = self.get_list_editable(request)
return super(MyAdminClass, self).get_changelist_instance(request)