根据条件在 django admin 中禁用或只读非模型字段
Make non-model field disabled or readonly in djnago admin based on condition
我有它的模型、管理员和表单。但是我的表单中有一个字段不在模型中,我正在对该字段执行一些自定义操作。
我希望此字段对没有某些权限的用户只读或隐藏或禁用,但 django 不允许我动态设置任何这些属性。
我的模特:
class PromocodePool(TimeStampedModel):
start = models.DateTimeField()
end = models.DateTimeField(null=True, blank=True)
表格:
class PromocodePoolForm(forms.ModelForm):
promocodes = forms.FileField(widget=AdminFileWidget, required=False) # this field is non-model
class Meta:
model = PromocodePool
fields = '__all__'
管理员:
@admin.register(PromocodePool)
class PromocodePoolAdmin(admin.ModelAdmin):
form = PromocodePoolForm
list_display = ("get_start", "get_end")
readonly_fields = (<some fields, tuple>)
@admin.display(description="Start date")
def get_start(self, obj):
return _date(obj.start, formats.DATE_FORMAT)
@admin.display(description="Start date")
def get_end(self, obj):
return _date(obj.end, formats.DATE_FORMAT)
def get_readonly_fields(self, request, obj=None):
if not request.user.has_perm("promocode.custom_permission"):
self.readonly_fields += ("promocodes",) # this doesn't work
return self.readonly_fields
我收到此错误:
Unable to lookup 'promocodes' on PromocodePool or PromocodePoolAdmin or PromocodePoolForm
顺便说一句,如果我重命名我的表单,错误文本保持不变,因为真正的“完成”表单是通过 django 的 ModelFormMetaclass 生成的,并且称为 PromocodePoolForm,而这个表单不是我上面描述的表单。
有什么方法可以动态禁用这个字段吗?
如果重要,我使用 python 3.8 和 Django 3.2.6
谢谢 我进一步搜索并解决了我的问题。
我制作了两个表格 classes 而不是我以前的一个
class PromocodePoolForm(forms.ModelForm):
promocodes = forms.FileField(widget=AdminFileWidget, required=False, disabled=True)
# no validation/processing for this non-model field in this class
# just disabled field
class Meta:
model = PromocodePool
fields = '__all__'
class PromocodePoolFormNotDisabled(PromocodePoolForm):
promocodes = forms.FileField(widget=AdminFileWidget, required=False)
# all validation/processing for non-model field is in this class now
并将此方法添加到管理 class 而不是 get_readonly_fields
@admin.register(PromocodePool)
class PromocodePoolAdmin(admin.ModelAdmin):
form = PromocodePoolForm
...
def get_form(self, request, obj=None, change=False, **kwargs):
if request.user.has_perm("promocode.custom_permission"):
self.form = PromocodePoolFormNotDisabled
return super().get_form(request, obj, change, **kwargs)
它就像一个魅力:如果用户没有权限,他会得到带有禁用字段的表单,否则他会得到正常的。
看来,您可以覆盖 get_forms 方法,在那里检查用户自定义权限,并返回您的自定义表单。我不知道,当然,这是一个很好的方法,但在我的情况下它有效)
我有它的模型、管理员和表单。但是我的表单中有一个字段不在模型中,我正在对该字段执行一些自定义操作。
我希望此字段对没有某些权限的用户只读或隐藏或禁用,但 django 不允许我动态设置任何这些属性。
我的模特:
class PromocodePool(TimeStampedModel):
start = models.DateTimeField()
end = models.DateTimeField(null=True, blank=True)
表格:
class PromocodePoolForm(forms.ModelForm):
promocodes = forms.FileField(widget=AdminFileWidget, required=False) # this field is non-model
class Meta:
model = PromocodePool
fields = '__all__'
管理员:
@admin.register(PromocodePool)
class PromocodePoolAdmin(admin.ModelAdmin):
form = PromocodePoolForm
list_display = ("get_start", "get_end")
readonly_fields = (<some fields, tuple>)
@admin.display(description="Start date")
def get_start(self, obj):
return _date(obj.start, formats.DATE_FORMAT)
@admin.display(description="Start date")
def get_end(self, obj):
return _date(obj.end, formats.DATE_FORMAT)
def get_readonly_fields(self, request, obj=None):
if not request.user.has_perm("promocode.custom_permission"):
self.readonly_fields += ("promocodes",) # this doesn't work
return self.readonly_fields
我收到此错误:
Unable to lookup 'promocodes' on PromocodePool or PromocodePoolAdmin or PromocodePoolForm
顺便说一句,如果我重命名我的表单,错误文本保持不变,因为真正的“完成”表单是通过 django 的 ModelFormMetaclass 生成的,并且称为 PromocodePoolForm,而这个表单不是我上面描述的表单。
有什么方法可以动态禁用这个字段吗?
如果重要,我使用 python 3.8 和 Django 3.2.6
谢谢
我制作了两个表格 classes 而不是我以前的一个
class PromocodePoolForm(forms.ModelForm):
promocodes = forms.FileField(widget=AdminFileWidget, required=False, disabled=True)
# no validation/processing for this non-model field in this class
# just disabled field
class Meta:
model = PromocodePool
fields = '__all__'
class PromocodePoolFormNotDisabled(PromocodePoolForm):
promocodes = forms.FileField(widget=AdminFileWidget, required=False)
# all validation/processing for non-model field is in this class now
并将此方法添加到管理 class 而不是 get_readonly_fields
@admin.register(PromocodePool)
class PromocodePoolAdmin(admin.ModelAdmin):
form = PromocodePoolForm
...
def get_form(self, request, obj=None, change=False, **kwargs):
if request.user.has_perm("promocode.custom_permission"):
self.form = PromocodePoolFormNotDisabled
return super().get_form(request, obj, change, **kwargs)
它就像一个魅力:如果用户没有权限,他会得到带有禁用字段的表单,否则他会得到正常的。
看来,您可以覆盖 get_forms 方法,在那里检查用户自定义权限,并返回您的自定义表单。我不知道,当然,这是一个很好的方法,但在我的情况下它有效)