Reusable Code In Multiple Views


#1

I created a contact form based on https://hellowebapp.com/news/tutorial-setting-up-a-contact-form-with-django and integrated SendGrid api and everything works peachy. But, I need to include this simple contact form on several views but don’t want to repeat the code on every view. How do I create a service or shared function that will allow me to set tup the code once but then call it in any view that I need it?

Thank you,
Chuck

@shazow - Any thoughts?


#2

You can use django’s {% include ... %} directive to include snippets in various templates.

Django’s docs on it are here: https://docs.djangoproject.com/en/1.9/ref/templates/builtins/#include

Basically you’d put your contact form into something like contact_snippet.html, then wherever you wanted to include the form you’d do {% include "contact_snippet.html" %}, this way you’ll only need to maintain what the form looks like in one place. :)


#3

Thanks @shazow - I know about the {% include … %} directive to insert the html portion of the form, but if I have the methods defined in my contact view as such:

def contact(request):
    form_class = ContactForm

    if request.method == 'POST':
        form = form_class(data=request.POST)

        ...

            return redirect('contact')

    return render(request, 'pages/contact.html', {
        'form': form_class,
    })

How do I include the html on another view when the method is defined in the ‘contact’ view? Does this make sense, or is my noob slip showing? :)


#4

Nah, that’s a totally legit question. :)

Realistically, if you’re using Django forms, you’d need to include the form class in every view that includes that form.

That said, you don’t need to necessarily include the form processing logic in every view (the stuff inside if request.method == 'POST': ...), I’d just submit the form into the contact view regardless of which view you’re on.

So it might look something like this:

def otherview(request):
    return render(request, 'otherviewincludingcontactsnippet.html', {
        'contact_form': ContactForm,
    })

Note I changed the form variable to contact_form so that it doesn’t conflict with other forms in that view. :)


#5

Thanks dude, that makes perfect sense…Do you think it would be more efficient and DRYer if I used ModelForm for my forms? Thanks again for you help :) Enjoy your holidays :)


#6

This part is fairly subjective. The best thing to do is give it a try and see how it ends up looking. It’s usually hard to predict what the best code design is without having very relevant experience in doing the same thing before. A quick adventure in trying a different design might end up being thrown away but that experience will be forever useful.

My personal preference is to avoid using Django forms altogether; my applications typically have fairly customized forms/functionality that trying to fit it into Django’s rigid schemas/validation is usually more pain than it’s worth. But if you’re doing fairly “normal” things, it should be fine. That said, I also tend to avoid using Django altogether, so I’m not a great example of your average Django user. :)