R-dubs
R-dubs

Reputation: 59

Django with Crispy-forms VariableDoesNotExist

I have been trying to load a form into a modal for about a week now and I just can't figure out what it is I'm doing wrong. It is a simple form for someone to send an email to me, and I started out trying to modularize the form and am now just trying to load it direcly into base.html.

My model:

from django.db import models

# Create your models here.

class EmailMe(models.Model):
    subject = models.CharField(max_length=63)
    body = models.TextField(max_length=2047)
    email = models.EmailField()

    def __str__(self):#shows object title when called from command line
        return self.name`

my form:

from django import forms

from crispy_forms.helper import FormHelper
from crispy_forms.layout import Submit, Layout

from emailme.models import EmailMe

class EmailMeForm(forms.ModelForm):

    subject = forms.CharField(max_length=63)
    body = forms.CharField(max_length=2047)
    email = forms.EmailField()

    class Meta:
        model = EmailMe
        fields = '__all__'

    def __str__(self):#shows object title when called from command line
        return self.name

    def __init__(self, *args, **kwargs):
        super(EmailMeForm, self).__init__(*args, **kwargs)
        self.helper = FormHelper()
        self.helper.form_id = 'myModal'
        self.helper.form_class = 'form-horizontal'
        self.helper.form_action = 'emailme'
        self.helper.form_method = 'POST'
        self.helper.layout = Layout(
            Fields(
                'subject',
                'body',
                'email',
            ),
            FormActions(
                Submit('submit', 'submit')
            )
        )

My view:

from mysite.forms import EmailMeForm

def home(request):
    return render_to_response('base.html')

def emailme(request):
    if request.POST:
        form = EmailMeForm(request.POST)
        if form.is_valid():
            return HttpResponseRedirect('home/')#reverse_lazy('home'))
    else:
        form = EmailMeForm()


    ctx = {}
    ctx.update(csrf(request))

    args['form'] = form
    return render_to_response('emailme_form.html',
              {'form': form},
              context_instance=ctx)

urls:

"""mysite URL Configuration

"""
from django.conf.urls import url, include
from django.contrib import admin

from mysite import views as mysite_views
from emailme import views as emailme_views

urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^emailme/', emailme_views.emailme, name='emailme'),
url(r'^home/', mysite_views.home, name='home'),
]

base.html:

{% load crispy_forms_tags %}

<div class="modal-content">
      {% csrf_token %}
      {% crispy form form.helper %}
</div>

I'm using Django 1.9, crispy-forms, and bootstrap. Here is the error:

Environment:


Request Method: GET
Request URL: http://127.0.0.1:8000/home/

Django Version: 1.9.8
Python Version: 3.5.2
Installed Applications:
['django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
  'emailme',
  'crispy_forms',
 'bootstrap3']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
  'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']


Template error:
In template /home/pi/Django-bootstrap/bin/mysite/templates/base.html, error at line 77
  Failed lookup for key [%s] in %r   67 :     
    68 :     
 69 :     
 70 :  <div class="container">
 71 :   <!-- Modal -->
 72 :   <div class="modal fade" id="myModal" role="dialog">
 73 :   <div class="modal-dialog">





74 :   <!-- Modal content-->
75 :     <div class="modal-content">
76 :       {% csrf_token %}
 77 :        {% crispy form form.helper %} 
78 :     </div>
79 : </div>
80 :   </div>
81 :  </div>
82 : 
83 : 
84 : 
85 :     <div class="container">
86 :       <!-- Example row of columns -->
87 :       <div class="row">   


Traceback:

File "/home/pi/Django-bootstrap/lib/python3.5/site-packages/django/template/base.py" in _resolve_lookup
883.                     current = current[bit]

File "/home/pi/Django-bootstrap/lib/python3.5/site-packages/django/template/context.py" in __getitem__
 77.         raise KeyError(key)

During handling of the above exception ('form'), another exception occurred:

File "/home/pi/Django-bootstrap/lib/python3.5/site-packages/django/template/base.py" in _resolve_lookup
 889.                         if isinstance(current, BaseContext) and getattr(type(current), bit):

During handling of the above exception (type object 'Context' has no attribute 'form'), another exception occurred:

File "/home/pi/Django-bootstrap/lib/python3.5/site-packages/django/template/base.py" in _resolve_lookup
898.                             current = current[int(bit)]

During handling of the above exception (invalid literal for int() with base 10: 'form'), another exception occurred:

File "/home/pi/Django-bootstrap/lib/python3.5/site-packages/django/core/handlers/base.py" in get_response
149.                     response = self.process_exception_by_middleware(e, request)

File "/home/pi/Django-bootstrap/lib/python3.5/site-packages/django/core/handlers/base.py" in get_response
147.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "/home/pi/Django-bootstrap/bin/mysite/mysite/views.py" in home
13.     return render_to_response('base.html')

File "/home/pi/Django-bootstrap/lib/python3.5/site-packages/django/shortcuts.py" in render_to_response
39.         content = loader.render_to_string(template_name, context, using=using)

File "/home/pi/Django-bootstrap/lib/python3.5/site-packages/django/template/loader.py" in render_to_string
97.         return template.render(context, request)

File "/home/pi/Django-bootstrap/lib/python3.5/site-packages/django/template/backends/django.py" in render
95.             return self.template.render(context)

File "/home/pi/Django-bootstrap/lib/python3.5/site-packages/django/template/base.py" in render
206.                     return self._render(context)

File "/home/pi/Django-bootstrap/lib/python3.5/site-packages/django/template/base.py" in _render
197.         return self.nodelist.render(context)

File "/home/pi/Django-bootstrap/lib/python3.5/site-packages/django/template/base.py" in render
992.                 bit = node.render_annotated(context)

File "/home/pi/Django-bootstrap/lib/python3.5/site-packages/django/template/base.py" in render_annotated
959.             return self.render(context)

File "/home/pi/Django-bootstrap/lib/python3.5/site-packages/crispy_forms/templatetags/crispy_forms_tags.py" in render
214.         c = self.get_render(context)

File "/home/pi/Django-bootstrap/lib/python3.5/site-packages/crispy_forms/templatetags/crispy_forms_tags.py" in get_render
107.         actual_form = form.resolve(context)

File "/home/pi/Django-bootstrap/lib/python3.5/site-packages/django/template/base.py" in resolve
850.             value = self._resolve_lookup(context)

File "/home/pi/Django-bootstrap/lib/python3.5/site-packages/django/template/base.py" in _resolve_lookup
905.                                                        (bit, current))  # missing attribute

Exception Type: VariableDoesNotExist at /home/
Exception Value: Failed lookup for key [form] in "[{'False': False, 'None': None, 'True': True}]"

Upvotes: 1

Views: 2202

Answers (1)

solarissmoke
solarissmoke

Reputation: 31404

The problem is that you are trying to use your form in your base.html (for all views). But the form is only added to the context in your emailme view. The home page view (home) does not provide any form, hence the error when you try to load the home page.

You either need to add the form to the home page view (and any other views that use base.html):

def home(request):
    return render_to_response('base.html', {'form': EmailMeForm()})

or use a context processor to insert the form into to the template context globally.

Upvotes: 3

Related Questions