2

I have this code in context_processors.py

class ContactFormView(FormView):
    form_class = ContactForm
    template_name = "blog/contact.html"
    success_url = "/contact/"
    def form_valid(self,form):
       contact_name = form.cleaned_data.get('contact_name')
       contact_email = form.cleaned_data.get('contact_email')
       form_content  = form.cleaned_data.get('content','')
       try:
          send_mail(contact_name,form_content,contact_email,[settings.EMAIL_HOST_USER], fail_silently=False)
       except BadHeaderError:
          return HttpResponse('Invalid Header Found')
       return super(ContactFormView,self).form_valid(form)

I want to include this in all the views by using context processors.I am getting this error:

TypeError at /
__init__() takes exactly 1 argument (2 given)
Request Method: GET
Request URL:    http://127.0.0.1:8000/
Django Version: 1.8.7
Exception Type: TypeError
Exception Value:    
__init__() takes exactly 1 argument (2 given)
Exception Location: C:\Python27\lib\site-packages\django-1.8.7-py2.7.egg\django\template\context.py in bind_template, line 241
Python Executable:  C:\Python27\python.exe
Python Version: 2.7.10

How to pass this form in all the template?

Wtower
  • 18,848
  • 11
  • 103
  • 80
Aniket Pawar
  • 2,641
  • 19
  • 32
  • Instead of posting an image to an error *post the actual text* along with the code needed to reproduce it (i.e also stack trace) – Sayse Jan 05 '16 at 08:04
  • okk as a newbie taking your advice as positive .. – Aniket Pawar Jan 05 '16 at 08:17
  • This question makes absolutely no sense. A view is a view, not a context processor. – Daniel Roseman Jan 05 '16 at 08:24
  • @Daniel Roseman why? i want to include class based form in all the templates so i included it in context_processor to access on every templlate!! – Aniket Pawar Jan 05 '16 at 08:32
  • 3
    But a context processor is not a view. A context processor is a function that takes a request and returns a dictionary to add to the context; a view is much more complex and returns a full HTTP response. – Daniel Roseman Jan 05 '16 at 08:56

2 Answers2

8

I don't think you understand the concept of context processors. These are simple functions add things to the context which is a dictionary that is managed by django and sent to each and every template.

Context processors allow you to add your own keys and values to this dictionary, which are then available across all your templates.

In a context processor you just return a dictionary with your custom key/value pair - nothing more, for example:

from someapp.forms import ContactForm

def ctx_contact_form(request):
    return {'contact-form': ContactForm()}

Now, in all templates you'll have {{ contact-form }} available. Keep in mind you'll still have to write the surrounding HTML in your templates:

<form method="post" action="{% url 'your-view' %}">
   {{ contact-form }}
   <input type="submit">
</form>

If you want even that part to be written for you, so all you have to do in your templates is enter {{ contact-form }}, then you need to write a custom template tag, which involves a few steps.

First, create a simple template, lets say _formtag.html, and include the HTML from above:

<form method="post" action="{% url 'your-view' %}">
       {{ contact-form }}
       <input type="submit">
</form>

Next, create a directory called templatetags in your application, inside it, create an empty file called __init__.py, then create another file call it app_form_tags.py; in this app_form_tags.py file, add the following code:

from django import template
from yourapp.forms import ContactForm

register = template.Library()

@register.inclusion_tag('_formtag.html')
def contact_form():
    return {'contact-form': ContactForm()}

Finally, wherever you want to show that form (in the templates), just add

{% load app_form_tags %}

at the top of the file, and then {% contact_form %} where you want the form to go.

The rest of your code - that is, to process the form, will have to be written in the views as normal.

Burhan Khalid
  • 169,990
  • 18
  • 245
  • 284
  • thank you so much for response .. I actually knows the concept of this context processors but don't know that how to use forms with it ! Thank you again! – Aniket Pawar Jan 05 '16 at 09:25
  • Burhan Khalid, thank you very much for this clear answer. This helped me to get what I need. I have 1 question. I tried both ways (processor and templatetag). It is not clear to me which one is preferable to use. Could you tell me the difference? Both solve the same problem (login form). – TitanFighter Aug 30 '16 at 16:34
1

Thanks @Burhan Khalid !! I found a solution from your answer.

firstly i included my form( actually a crispy-form) in my context_processor

from .forms import ContactForm
    def contform(request):
        somevariable = {}
        somevariable['contform'] = ContactForm()
        return somevariable

Finally in any template :

{% crispy contform %}
Aniket Pawar
  • 2,641
  • 19
  • 32