首页 > 解决方案 > Django admin get_readonly_fields 不一致的行为

问题描述

我有与其他线程相同的请求,我使用的是 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__()方法内部完成一些事情,但我阅读了另一个线程的答案,其中关于内联管理元素,据说它没有意义,与我所相信的相反,因为:

在init中设置这样的值也是没有意义的,因为 Modeladmin 实例只创建一次,并且可能会持续不止一个请求!

所以现在我完全糊涂了。如何在 ModelAdmin 页面上为每个请求授予更新,以使我的只读字段逻辑的行为保持一致?

__init__()在我这边,我尝试使用该方法获取内部对象,get_object()但我需要提供我仍然不知道如何访问的对象 ID。但是,如果我在上面阅读的内容属实,那么向构造函数提供逻辑仍然是无用的,因为无论如何实例的持续时间都比请求长。

也许我应该使用get_form()或在我的情况下处理表单get_formsets_with_inlines()并自定义这些方法?但是我如何确保它们在每次请求时重新生成?

标签: djangodjango-modelsdjango-formsdjango-admininit

解决方案


pagato设置为 True 时,您将readonly_fields使用以下行覆盖该属性:

self.readonly_fields = ['utente', 'abbonamento', 'importo', 'giorni_attivi_abbonamento', 'data']

所以当pagato再次设置为 False 时,get_readonly_fields返回更新版本而不是原始版本。

试试这个:

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"]

推荐阅读