I'm trying to put multiple account management forms on the one page with a TemplateView
as follows:
class AccountManagement(TemplateView):
""" Generic view to display the account management template """
template_name = 'accountmanagement.html'
def get_context_data(self, **kwargs):
context = super(AccountManagement, self).get_context_data(**kwargs)
context['user'] = self.request.user
# pass unbound form instances to context
# if there aren't bound instances already there
if context.get('usercreate_form') is None:
context['usercreate_form'] = UserCreateForm()
if context.get('password_form') is None:
context['password_form'] = PasswordChangeForm()
return context
I'm handling UserCreation with a FormView
(because this example is simplified; I also need some non-model data, and CreateView needs a ModelForm). This view processes the POST
request, and is supposed to redirect to the TemplateView
with a success message, or pass the invalid bound form back to the context so that the template can render the errors. Trouble is, it doesn't do the part in bold italics (obviously HttpResponseRedirect
doesn't pass the context). Why? How can I get the bound form back into the TemplateView context here so that the form.errors
will be available and the user doesn't have to retype the data?
class UserCreate(FormView):
"""
Generic view to create a User.
"""
form_class = UserCreateForm
http_method_names = ['post',]
success_url = reverse_lazy('accountmanagement')
failure_url = reverse_lazy('accountmanagement')
def form_valid(self, form):
#password1 == password2 as per UserCreateForm.clean()
try:
new_user = User.objects.create_user(
username=form.cleaned_data['email'],
first_name=form.cleaned_data['first_name'],
last_name=form.cleaned_data['last_name'],
email=form.cleaned_data['email'],
password=form.cleaned_data['password1']
)
new_user.save()
messages.success(self.request, new_user.username + str(_(": successfully saved.") ))
return HttpResponseRedirect(self.success_url)
except IntegrityError:
#duplicate username
messages.error(self.request, _("Duplicate email address."))
return HttpResponseRedirect(self.failure_url, {'usercreate_form': form})
def form_invalid(self, form):
messages.error(self.request, _("Unable to create user."))
return HttpResponseRedirect(self.failure_url, {'usercreate_form': form})
template:
<form method="post" action="{% url 'usercreate' %}">{% csrf_token %}
{{ usercreate_form.errors }}
{{ usercreate_form.as_p }}
<button type="submit">{% trans 'Save' %}</button>
Final related question: is the right way to put several related forms on the one page a TemplateView
? And then process non-model forms using a POST
-only FormView
with a redirect back to the TemplateView
? Or should I do this a different way?