【问题标题】:Clear all Form Fields on Validation Error in Django清除 Django 中验证错误的所有表单字段
【发布时间】:2017-04-15 10:47:35
【问题描述】:

我有一个简单的用户注册表单(在 forms.py 中):

from django.contrib.auth.models import User

class UserForm(forms.ModelForm):
    password = forms.CharField(widget=forms.PasswordInput
                               validators=[MinLengthValidator(6)])
    password_repeat = forms.CharField(widget=forms.PasswordInput)

    class Meta:
        model = User
        fields = ['username', 'password','password_repeat']

如果有人尝试输入内容但验证失败,我希望再次呈现相同的表单,但应清除所有字段。目前我的视图看起来像这样(在views.py中):

def signup(request):
    form = UserForm(request.POST or None)

    if form.is_valid():
        user = form.save(commit=False)
        username = form.cleaned_data['username']
        password = form.cleaned_data['password']
        password_repeat = form.cleaned_data['password-repeat']
        user.set_password(password)
        user.save()
        user = auth.authenticate(username=username, password=password)
        if user is not None and user.is_active:
            auth.login(request, user)
            return redirect('/')

return render(request, 'signup.html', {'form': form})

问题是form.fields['username'] 字段仍然包含输入的用户名并因此传递给渲染。

我一直在寻找解决方案,但找不到。我的猜测是该解决方案与我似乎没有得到的clean() 方法有关。

【问题讨论】:

    标签: python django forms


    【解决方案1】:

    要始终清除特定表单字段同时保留所有表单验证错误,您可以创建一个始终“忘记”其旧值的自定义输入小部件。例如:

    from django import forms
    
    class NonstickyTextInput(forms.TextInput):
        '''Custom text input widget that's "non-sticky"
        (i.e. does not remember submitted values).
        '''
        def get_context(self, name, value, attrs):
            value = None  # Clear the submitted value.
            return super().get_context(name, value, attrs)
    
    class MyForm(forms.Form):
        username = forms.CharField(widget=NonstickyTextInput())
        # ...
    

    参考:django.forms.Widget.get_context

    行为

    假设我们在这样的视图中使用MyForm

    from django.shortcuts import render, redirect
    from myapp.forms import MyForm
    
    def myview(request):
        if request.method == 'POST':
            form = MyForm(request.POST)
            if form.is_valid():
                # Do something with the submitted values...
                return redirect('home_page')
        else:
            form = MyForm()
        return render(request, 'myapp/myview.html', {'form': form})
    

    当表单遇到任何验证错误并重新显示表单时,所有通常的验证错误消息都会显示在表单上,​​但显示的username 表单字段将为空白。

    【讨论】:

      【解决方案2】:

      这是一件奇怪的事情 - 它与人们通常提出的问题相反,因为大多数人都希望保留字段并显示错误。

      但是,如果你真的想清除表单,你应该实例化一个新的。

      if form.is_valid():
          ...
      else:
          form = UserForm()
      return render(request, 'signup.html', {'form': form})
      

      【讨论】:

      • 是的,对不起,我应该把这件事弄清楚。我想显示错误但也清除所有字段。如果我只是实例化一个新表单,我会丢失错误消息。
      • 这不会保留表单验证错误。见stackoverflow.com/a/57264601
      猜你喜欢
      • 1970-01-01
      • 2017-08-06
      • 2013-05-26
      • 2011-03-10
      • 2017-09-14
      • 2013-08-30
      • 2017-06-19
      • 2020-10-15
      • 1970-01-01
      相关资源
      最近更新 更多