If I have two forms:
class ContactForm(forms.Form): name = forms.CharField() message = forms.CharField(widget=forms.Textarea) class SocialForm(forms.Form): name = forms.CharField() message = forms.CharField(widget=forms.Textarea)
and wanted to use a class based view, and send both forms to the template, is that even possible?
class TestView(FormView): template_name = 'contact.html' form_class = ContactForm
It seems the FormView can only accept one form at a time. In function based view though I can easily send two forms to my template and retrieve the content of both within the request.POST back.
variables = {'contact_form':contact_form, 'social_form':social_form } return render(request, 'discussion.html', variables)
Is this a limitation of using class based view (generic views)?
Many Thanks
A view is a callable which takes a request and returns a response. This can be more than just a function, and Django provides an example of some classes which can be used as views. These allow you to structure your views and reuse code by harnessing inheritance and mixins.
Create a Django project and an app, I named the project "multipleFormHandle" and the app as "formhandlingapp". Do some basic stuff like including app in settings.py INSTALLED_APPS and include app's url in project's url. Now create forms.py in app and a "templates" folder in the app directory. Add home.
To decorate every instance of a class-based view, you need to decorate the class definition itself. To do this you apply the decorator to the dispatch() method of the class. The decorators will process a request in the order they are passed to the decorator.
The most significant advantage of the class-based view is inheritance. In the class-based view, you can inherit another class, and it can be modified for the different use cases. It helps you in following the DRY principle. You won't have to write the same code over and over in your boilerplate.
Here's a scaleable solution. My starting point was this gist,
https://gist.github.com/michelts/1029336
i've enhanced that solution so that multiple forms can be displayed, but either all or an individual can be submitted
https://gist.github.com/jamesbrobb/748c47f46b9bd224b07f
and this is an example usage
class SignupLoginView(MultiFormsView): template_name = 'public/my_login_signup_template.html' form_classes = {'login': LoginForm, 'signup': SignupForm} success_url = 'my/success/url' def get_login_initial(self): return {'email':'[email protected]'} def get_signup_initial(self): return {'email':'[email protected]'} def get_context_data(self, **kwargs): context = super(SignupLoginView, self).get_context_data(**kwargs) context.update({"some_context_value": 'blah blah blah', "some_other_context_value": 'blah'}) return context def login_form_valid(self, form): return form.login(self.request, redirect_url=self.get_success_url()) def signup_form_valid(self, form): user = form.save(self.request) return form.signup(self.request, user, self.get_success_url())
and the template looks like this
<form class="login" method="POST" action="{% url 'my_view' %}"> {% csrf_token %} {{ forms.login.as_p }} <button name='action' value='login' type="submit">Sign in</button> </form> <form class="signup" method="POST" action="{% url 'my_view' %}"> {% csrf_token %} {{ forms.signup.as_p }} <button name='action' value='signup' type="submit">Sign up</button> </form>
An important thing to note on the template are the submit buttons. They have to have their 'name' attribute set to 'action' and their 'value' attribute must match the name given to the form in the 'form_classes' dict. This is used to determine which individual form has been submitted.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With