Django: Can class-based views accept two forms at a time?

前端 未结 7 2374
说谎
说谎 2020-11-29 17:50

If I have two forms:

class ContactForm(forms.Form):
    name = forms.CharField()
    message = forms.CharField(widget=forms.Textarea)

class SocialForm(forms         


        
7条回答
  •  被撕碎了的回忆
    2020-11-29 18:19

    I have used a following generic view based on TemplateView:

    def merge_dicts(x, y):
        """
        Given two dicts, merge them into a new dict as a shallow copy.
        """
        z = x.copy()
        z.update(y)
        return z
    
    
    class MultipleFormView(TemplateView):
        """
        View mixin that handles multiple forms / formsets.
        After the successful data is inserted ``self.process_forms`` is called.
        """
        form_classes = {}
    
        def get_context_data(self, **kwargs):
            context = super(MultipleFormView, self).get_context_data(**kwargs)
            forms_initialized = {name: form(prefix=name)
                                 for name, form in self.form_classes.items()}
    
            return merge_dicts(context, forms_initialized)
    
        def post(self, request):
            forms_initialized = {
                name: form(prefix=name, data=request.POST)
                for name, form in self.form_classes.items()}
    
            valid = all([form_class.is_valid()
                         for form_class in forms_initialized.values()])
            if valid:
                return self.process_forms(forms_initialized)
            else:
                context = merge_dicts(self.get_context_data(), forms_initialized)
                return self.render_to_response(context)
    
        def process_forms(self, form_instances):
            raise NotImplemented
    

    This has the advantage that it is reusable and all the validation is done on the forms themselves.

    It is then used as follows:

    class AddSource(MultipleFormView):
        """
        Custom view for processing source form and seed formset
        """
        template_name = 'add_source.html'
        form_classes = {
            'source_form': forms.SourceForm,
            'seed_formset': forms.SeedFormset,
        }
    
        def process_forms(self, form_instances):
            pass # saving forms etc
    

提交回复
热议问题