[英]When you exclude a field from a Django admin class, does that also prevent the field being set in a POST?
Say I have a model admin:假设我有一个 model 管理员:
class Customer(Model):
name = CharField(max_length=255)
secret = CharField(max_length=255, blank=True)
@register(Customer)
class CustomerAdmin(ModelAdmin):
list_display = ['name']
exclude = ['secret']
The secret
field is not going to appear in the admin. secret
字段不会出现在管理员中。 But if I programmatically create a POST
with the secret
field in, will Django prevent it from being set on the model?但是,如果我以编程方式创建一个包含
secret
字段的POST
,Django 会阻止它在 model 上设置吗? So is there any security risk in having an admin class for a model which has excluded fields that should not be written to from a web client?那么对于 model 的管理员 class 是否存在任何安全风险,其中排除了不应从 web 客户端写入的字段?
Answer is that this should be fine and using exclude
should be enough to prevent the field being set by a malicious POST.答案是这应该没问题,并且使用
exclude
应该足以防止该字段被恶意 POST 设置。
The reason lies in construct_instance()
(django 3.2) , which is used to populate a new or existing instance (the instance
argument) with data from the POST (in the fields
argument):原因在于
construct_instance()
(django 3.2) ,它用于使用来自 POST 的数据(在fields
参数中)填充新的或现有的实例( instance
参数):
def construct_instance(form, instance, fields=None, exclude=None):
...
for f in opts.fields:
...
if exclude and f.name in exclude:
continue
...
else:
f.save_form_data(instance, cleaned_data[f.name])
Which gets called as:这被称为:
class BaseModelForm(BaseForm):
...
def _post_clean(self):
opts = self._meta
...
try:
self.instance = construct_instance(self, self.instance, opts.fields, opts.exclude)
except ValidationError as e:
...
And the exclude
is populated by the django.contrib.admin.options.ModelAdmin
:并且
exclude
由django.contrib.admin.options.ModelAdmin
填充:
class ModelAdmin(BaseModelAdmin):
...
def get_exclude(self, request, obj=None):
return self.exclude
...
def get_form(self, request, obj=None, change=False, **kwargs):
...
excluded = self.get_exclude(request, obj)
exclude = [] if excluded is None else list(excluded)
...
defaults = {
...
'exclude': exclude,
...
}
...
try:
return modelform_factory(self.model, **defaults)
except FieldError as e:
...
And modelform_factory
just passes that through to the form's options.而
modelform_factory
只是将其传递给表单的选项。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.