在Django表单中,如何使字段只读(或禁用)以使其无法编辑?

2024-04-29 21:10:56 发布

您现在位置:Python中文网/ 问答频道 /正文

在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()

Tags: 模型formview编辑表单modelsrequest记录
3条回答

正如this answer中指出的,Django 1.9添加了Field.disabled属性:

The disabled boolean argument, when set to True, disables a form field using the disabled HTML attribute so that it won’t be editable by users. Even if a user tampers with the field’s value submitted to the server, it will be ignored in favor of the value from the form’s initial data.

对于Django 1.8和更早版本,要禁用小部件上的条目并防止恶意的后黑客攻击,除了在表单字段上设置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来排除不可编辑的字段,并将它们打印在模板中。

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

The disabled boolean argument, when set to True, disables a form field using the disabled HTML attribute so that it won’t be editable by users. Even if a user tampers with the field’s value submitted to the server, it will be ignored in favor of the value from the form’s initial data.

在widget上设置read only将使浏览器中的输入为只读。添加返回instance.sku的clean_sku可确保字段值不会在表单级别更改。

def clean_sku(self):
    if self.instance: 
        return self.instance.sku
    else: 
        return self.fields['sku']

这样,您就可以使用model的(未修改的save)和aviod获取字段所需的错误。

相关问题 更多 >