Tengo un formulario de registro de usuario simple (en 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']Si alguien intenta ingresar algo y la validación falla, quiero que se vuelva a procesar el mismo formulario, pero todos los campos deben borrarse. Por el momento, mi vista se ve así (en 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}) El problema es que el form.fields['username'] todavía contiene el nombre de usuario que se ingresó y, por lo tanto, se pasa a renderizar.
Llevo tiempo buscando una solución pero no la encuentro. Supongo que la solución tiene algo que ver con el método clean() que parece que no entiendo.
Esto es algo extraño de querer hacer: es lo opuesto a la pregunta que la gente normalmente hace, ya que la mayoría de la gente quiere conservar los campos y mostrar los errores.
Sin embargo, si realmente desea borrar el formulario, debe crear una instancia nueva.
if form.is_valid(): ... else: form = UserForm() return render(request, 'signup.html', {'form': form})Para borrar siempre un campo de formulario en particular y conservar todos los errores de validación de formulario, puede crear un widget de entrada personalizado que siempre "olvida" su valor anterior. Por ejemplo:
from django import forms class NonstickyTextInput(forms.TextInput): '''Custom text input widget that's "non-sticky" (ie 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()) # ...Referencia: django.forms.Widget.get_context
Comportamiento
Supongamos que estamos usando MyForm en tal vista:
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}) Cuando el formulario encuentra algún error de validación y se vuelve a mostrar, todos los mensajes de error de validación habituales se mostrarán en el formulario, pero el campo de formulario de nombre de username que se muestra estará en blanco.