Search code examples
djangodjango-formsdjango-templatesdjango-viewsdjango-csrf

How come the context of my form.py is not showing up?


I have had the same problem for quite some time and have been trying different solutions but nothing is working. I have seen different examples here on the website, but most of them are addressing older versions of Django. I have tried such solutions, but nothing is workin. The problem is as addressed by the title,

" A {% csrf_token %} was used in a template, but the context did not provide the value. This is usually caused by not using RequestContext. "

I have tried to add RequestContext(request) to my code instead of writing {'form': 'form'} but it didn't work out. I have tried to use HttpResponse() instead of render_to_response in my urls' views, but didn't work out as well.

This is the for my original views.py before I alter anything!

            def ask_page_view(request):
                if request.method == 'POST':
                    form = Ask_Page_Form(request.POST)
                    if form.is_valid():
                        pass  # does nothing, just trigger the validation
                else:
                    form = Ask_Page_Form()
                return render(request, "ask.html",  {'form': form })

This is the views.py when I have added the RequestContext()

        def ask_page_view(request):
            if request.method == 'POST':
                form = Ask_Page_Form(request.POST)
                if form.is_valid():
                    pass
                else:
                    form = Ask_Page_Form()
                return renderto('ask.html', context_instance = RequestContext(request))

This is the forms.py that I am using:

        from django import forms

        class Ask_Page_Form(forms.Form):
            name = forms.CharField(
                max_length=30,
                widget=forms.TextInput(
                        attrs={
                                'placeholder': 'Write your name here',
                                'class': 'ask-page-input',
                                'label': 'Student Name'
                            }
            ))
            email = forms.EmailField(
                max_length=254,
                widget=forms.EmailInput(
                        attrs={
                                'placeholder': 'Write your Email here',
                                'class': 'ask-page-input',
                                'label': 'Email'
                            }
            ))
            subject = forms.CharField(
                max_length=50,
                widget = forms.TextInput(
                        attrs={
                                'placeholder': 'Write your Question or Related Subject here',
                                'class': 'ask-page-input',
                                'label': 'Subject'
                            }
            ))

            message = forms.CharField(
                max_length=2000,
                widget=forms.Textarea(
                        attrs={
                                'placeholder': 'Write your message here',
                                'class': 'ask-page-input',
                                'label': 'Message'
                            }
            ))


            source = forms.CharField(       # A hidden input for internal use
                max_length=50,              # tell from which page the user sent the message
                widget=forms.HiddenInput()
            )

            def clean(self):
                cleaned_data = super(Ask_Page_Form, self).clean()
                name = cleaned_data.get('name')
                email = cleaned_data.get('email')
                subject = cleaned_data.get('subject')
                message = cleaned_data.get('message')
                if not name and not email and not subject and not message:
                    raise forms.ValidationError('You have to write something!')

This is the HTML

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Physics Quizzes Ask</title>
  </head>
  <body>
    <form method="POST">
      {% csrf_token %}
      {{ form.as_p }}
    </form>
  </body>
</html>

I would like to have four input fields where the user can type whatever question that he/ she thinks about and then send it with a submit button to the admin's email. But the fields are not showing up and only the button does. Thank you :)


Solution

  • In order to generate the form you need to call the view:

    html:

    <a href="/your_app_name/ask_page_view">create form</a> 
    <form method="POST">{% csrf_token %}
      {{ form.as_p }}
      <input type="submit" name="submit">
    </form>
    

    your_app's urls.py:

    url(r'ask_page_view/$', views.ask_page_view),
    

    view.py:

    from django.template.context_processors import csrf
    
    def ask_page_view(request):
        if request.method == 'POST':
           form = Ask_Page_Form(request.POST) 
           if form.is_valid(): # here you validate the created form
              pass  # does nothing, just trigger the validation
           else:
              form = Ask_Page_Form() # here you create a new form          
    
           args = {}
           args.update(csrf(request))
           args['form'] = form
        return render(request, "ask.html", args)