如何在Django中设置表单为只读时防止数据篡改?

18 浏览
0 Comments

如何在Django中设置表单为只读时防止数据篡改?

在Django表单中,如何使一个字段只读(或禁用)?当表单用于创建新条目时,所有字段应该是可用的 - 但是当记录处于更新模式时,部分字段需要是只读的。

例如,在创建新的Item模型时,所有字段都必须是可编辑的,但是在更新记录的时候,是否有一种方法可以使sku字段不可编辑,从而可见但无法编辑?

class Item(models.Model):
    sku = models.CharField(max_length=50)
    description = models.CharField(max_length=200)
    added_by = models.ForeignKey(User)
class ItemForm(ModelForm):
    class Meta:
        model = Item
        exclude = ('added_by')
def new_item_view(request):
    if request.method == 'POST':
        form = ItemForm(request.POST)
        # Validate and save
    else:
            form = ItemForm()
    # Render the view

可以重复使用类ItemForm吗?在ItemFormItem模型类中需要进行哪些更改?我是否需要编写另一个类,\"ItemUpdateForm\",来更新项目?

def update_item_view(request):
    if request.method == 'POST':
        form = ItemUpdateForm(request.POST)
        # Validate and save
    else:
        form = ItemUpdateForm()

admin 更改状态以发布 2023年5月21日
0
0 Comments

Django 1.9增加了Field.disabled属性:https://docs.djangoproject.com/en/stable/ref/forms/fields/#disabled

当将disabled布尔值参数设置为True时,将使用disabled HTML属性禁用表单字段,以便用户无法编辑它。即使用户篡改了提交到服务器的字段值,也将忽略它,转而使用表单初始数据中的值。

0
0 Comments

正如这个答案中指出的那样,Django 1.9添加了Field.disabled属性:

当disabled布尔值参数设置为True时,会使用disabled HTML属性禁用表单字段,以使用户无法对其进行编辑。即使用户篡改提交到服务器的字段值,也会忽略它们而使用表单的初始数据的值。

在Django 1.8及更早的版本中,为了禁用小部件上的输入并防止恶意POST黑客攻击,您必须除了设置readonly属性之外还要清理输入内容:

class ItemForm(ModelForm):
    def __init__(self, *args, **kwargs):
        super(ItemForm, self).__init__(*args, **kwargs)
        instance = getattr(self, 'instance', None)
        if instance and instance.pk:
            self.fields['sku'].widget.attrs['readonly'] = True
    def clean_sku(self):
        instance = getattr(self, 'instance', None)
        if instance and instance.pk:
            return instance.sku
        else:
            return self.cleaned_data['sku']

或者,将if instance and instance.pk替换为另一个表明您正在编辑的条件。您还可以在输入字段上设置disabled属性,而不是readonly属性。

clean_sku函数将确保readonly值不会被POST覆盖。

否则,没有内置的Django表单字段会呈现一个拒绝绑定输入数据的值。如果这是您所需的,您应该创建一个单独的ModelForm,其中排除了不可编辑的字段,并在模板内部仅打印它们。

0