Django 管理员 get_readonly_fields 不一致的行为
Django admin get_readonly_fields inconsistent behavior
我有与 this other thread 相同的请求,我使用的是 Django 3.2.8
对于我的项目,管理页面中的某些字段必须根据同一模型对象的一个布尔字段的值变为只读,因此我应用了上面另一个线程中建议的解决方案。
class OrdineAdmin(admin.ModelAdmin):
inlines = [
FatturaAdmin
]
readonly_fields = ["data"]
def get_readonly_fields(self, request, obj=None):
if obj and obj.pagato == True:
self.readonly_fields = ['utente', 'abbonamento', 'importo', 'giorni_attivi_abbonamento', 'data']
return self.readonly_fields
如我所料,此解决方案会导致管理面板出现一些不一致,因为 OrdineAdmin 的一个实例会在内存中生成,但它不会根据每个请求进行更新。因此,当我将字段“pagato”设置为 True 时,此方法会按预期将所有其他字段设置为只读,但如果我将该字段设置回 False,即使通过管理面板的保存过程成功,也不会逆转其效果。
这就是为什么我认为需要在 __init__()
方法中完成一些事情,但我阅读了 this other thread 的答案,其中关于内联管理元素据说它不会'与我所相信的相反,这没有道理,因为:
It also makes no sense to set values like that in init, since the Modeladmin instance is created once and may persist for a lot more than one request!
所以现在我完全糊涂了。我如何为 ModelAdmin 页面上的每个请求授予更新,以实现我的只读字段逻辑的一致行为?
在我这边,我尝试使用 get_object()
方法获取 __init__()
中的对象,但我需要提供对象 ID,但我仍未弄清楚如何访问.但是如果我在上面读到的是真的,那么向构造函数提供逻辑仍然是无用的,因为无论如何实例都会比请求持续更长时间。
也许我应该用 get_form()
或在我的情况下 get_formsets_with_inlines()
来处理表单并自定义这些方法?但是我如何确保它们在每次请求时都重新生成?
当 pagato
设置为 True 时,您可以使用以下行覆盖 readonly_fields
属性:
self.readonly_fields = ['utente', 'abbonamento', 'importo', 'giorni_attivi_abbonamento', 'data']
因此当 pagato
再次设置为 False 时,get_readonly_fields
returns 更新版本而不是原始版本。
试试这个:
class OrdineAdmin(admin.ModelAdmin):
inlines = [
FatturaAdmin
]
readonly_fields = ["data"]
def get_readonly_fields(self, request, obj=None):
if obj and obj.pagato == True:
return ['utente', 'abbonamento', 'importo', 'giorni_attivi_abbonamento', 'data']
return self.readonly_fields
或者更简洁:
class OrdineAdmin(admin.ModelAdmin):
inlines = [
FatturaAdmin
]
def get_readonly_fields(self, request, obj=None):
if obj and obj.pagato == True:
return ['utente', 'abbonamento', 'importo', 'giorni_attivi_abbonamento', 'data']
return ["data"]
我有与 this other thread 相同的请求,我使用的是 Django 3.2.8
对于我的项目,管理页面中的某些字段必须根据同一模型对象的一个布尔字段的值变为只读,因此我应用了上面另一个线程中建议的解决方案。
class OrdineAdmin(admin.ModelAdmin):
inlines = [
FatturaAdmin
]
readonly_fields = ["data"]
def get_readonly_fields(self, request, obj=None):
if obj and obj.pagato == True:
self.readonly_fields = ['utente', 'abbonamento', 'importo', 'giorni_attivi_abbonamento', 'data']
return self.readonly_fields
如我所料,此解决方案会导致管理面板出现一些不一致,因为 OrdineAdmin 的一个实例会在内存中生成,但它不会根据每个请求进行更新。因此,当我将字段“pagato”设置为 True 时,此方法会按预期将所有其他字段设置为只读,但如果我将该字段设置回 False,即使通过管理面板的保存过程成功,也不会逆转其效果。
这就是为什么我认为需要在 __init__()
方法中完成一些事情,但我阅读了 this other thread 的答案,其中关于内联管理元素据说它不会'与我所相信的相反,这没有道理,因为:
It also makes no sense to set values like that in init, since the Modeladmin instance is created once and may persist for a lot more than one request!
所以现在我完全糊涂了。我如何为 ModelAdmin 页面上的每个请求授予更新,以实现我的只读字段逻辑的一致行为?
在我这边,我尝试使用 get_object()
方法获取 __init__()
中的对象,但我需要提供对象 ID,但我仍未弄清楚如何访问.但是如果我在上面读到的是真的,那么向构造函数提供逻辑仍然是无用的,因为无论如何实例都会比请求持续更长时间。
也许我应该用 get_form()
或在我的情况下 get_formsets_with_inlines()
来处理表单并自定义这些方法?但是我如何确保它们在每次请求时都重新生成?
当 pagato
设置为 True 时,您可以使用以下行覆盖 readonly_fields
属性:
self.readonly_fields = ['utente', 'abbonamento', 'importo', 'giorni_attivi_abbonamento', 'data']
因此当 pagato
再次设置为 False 时,get_readonly_fields
returns 更新版本而不是原始版本。
试试这个:
class OrdineAdmin(admin.ModelAdmin):
inlines = [
FatturaAdmin
]
readonly_fields = ["data"]
def get_readonly_fields(self, request, obj=None):
if obj and obj.pagato == True:
return ['utente', 'abbonamento', 'importo', 'giorni_attivi_abbonamento', 'data']
return self.readonly_fields
或者更简洁:
class OrdineAdmin(admin.ModelAdmin):
inlines = [
FatturaAdmin
]
def get_readonly_fields(self, request, obj=None):
if obj and obj.pagato == True:
return ['utente', 'abbonamento', 'importo', 'giorni_attivi_abbonamento', 'data']
return ["data"]