eZ_Harry
eZ_Harry

Reputation: 826

Django Form Creating Attribute Error

I cannot tell why this form on the index page of my website is creating an attribute error whenever I add in some validation code. Can anyone see the problem?

Form Code -

region_choice = (
    ('', 'Region'),
    ('1', 'Auckland'),
    ('2', 'Wellington'),
    ('3', 'Christchurch')
)
suburb_choice = (
    ('', 'None'),
    ('1', 'Glendowie'),
    ('2', 'Kohimarama'),
    ('3', 'Herne Bay')
)
industry_choice = (
    ('', 'Business Industry'),
    ('1', 'Accounting'),
    ('2', 'Agriculture, fishing & forestry'),
    ('3', 'Automotive'),
    ('4', 'Banking, finance & insurance'),
    ('5', 'Construction & Architecture'),
    ('6', 'Customer service'),
)
employment_type_choice = (
    ('', 'None'),
    ('1', 'Full Time'),
    ('2', 'Part Time'),
    ('3', 'One-off'),
    ('4', 'Other')
)

class JobQuickSearchForm(forms.Form):
    business_address_region = forms.ChoiceField(region_choice, required=False, widget=forms.Select(attrs={'class': 'qs-form-input'}))
    business_industry = forms.ChoiceField(industry_choice, widget=forms.Select(attrs={'class': 'qs-form-input'}))
    keywords = forms.CharField(max_length=20, widget=forms.TextInput(attrs={'class': 'qs-form-input', 'placeholder': 'Enter Keywords...'}))

    def clean(self):
        if self.business_address_region and self.business_industry and self.keywords == '':
            raise ValidationError("You must specify either email or telephone")

View - (Am I instantiating the form right?)

def index(request):

    if request.method == "GET":
        form = JobQuickSearchForm(request.GET)

    context_dict = {
        "form": form
    }

    return render(request, 'index.html', context_dict)

Error -

Environment:


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

Django Version: 1.9.1
Python Version: 2.7.10
Installed Applications:
('django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'django.contrib.sites',
 'main',
 'listings',
 'profiles',
 'allauth',
 'allauth.account',
 'allauth.socialaccount')
Installed Middleware:
('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 D:\Other folders\Desktop\Student Job Search\code\opus_jobs_project\templates\index.html, error at line 8
   'JobQuickSearchForm' object has no attribute 'business_address_region'   1 : {% extends "base.html" %}
   2 : {% load static %}
   3 : 
   4 : {% block content %}
   5 :   <div id="quicksearch">
   6 :     <h1 class="pageheader">Where would you to like to work?</h1>
   7 :       <form class="qs-form" action="{% url 'browse' %}">
   8 :          {{ form.non_field_errors }} 
   9 :         {{ form.business_industry }}
   10 :         {{ form.business_address_region }}
   11 :         {{ form.keywords }}<br>
   12 :         <button type="submit" class="qs-form-button">Search Jobs</button>
   13 :       </form>
   14 :   </div>
   15 :   <div id="information">
   16 :     <h1 class="pageheader">How Opus Works</h1>
   17 :     <div class="information-div">
   18 :         <a href="{% url "account_signup" %}"><img src="{% static 'images/icon1.png' %}" ></img></a>


Traceback:

File "C:\Python27\Lib\site-packages\django\core\handlers\base.py" in get_response
  149.                     response = self.process_exception_by_middleware(e, request)

File "C:\Python27\Lib\site-packages\django\core\handlers\base.py" in get_response
  147.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "D:\Other folders\Desktop\Student Job Search\code\opus_jobs_project\main\views.py" in index
  13.     return render(request, 'index.html', context_dict)

File "C:\Python27\Lib\site-packages\django\shortcuts.py" in render
  67.             template_name, context, request=request, using=using)

File "C:\Python27\Lib\site-packages\django\template\loader.py" in render_to_string
  97.         return template.render(context, request)

File "C:\Python27\Lib\site-packages\django\template\backends\django.py" in render
  95.             return self.template.render(context)

File "C:\Python27\Lib\site-packages\django\template\base.py" in render
  206.                     return self._render(context)

File "C:\Python27\Lib\site-packages\django\template\base.py" in _render
  197.         return self.nodelist.render(context)

File "C:\Python27\Lib\site-packages\django\template\base.py" in render
  988.                 bit = node.render_annotated(context)

File "C:\Python27\Lib\site-packages\django\template\base.py" in render_annotated
  955.             return self.render(context)

File "C:\Python27\Lib\site-packages\django\template\loader_tags.py" in render
  173.         return compiled_parent._render(context)

File "C:\Python27\Lib\site-packages\django\template\base.py" in _render
  197.         return self.nodelist.render(context)

File "C:\Python27\Lib\site-packages\django\template\base.py" in render
  988.                 bit = node.render_annotated(context)

File "C:\Python27\Lib\site-packages\django\template\base.py" in render_annotated
  955.             return self.render(context)

File "C:\Python27\Lib\site-packages\django\template\loader_tags.py" in render
  69.                 result = block.nodelist.render(context)

File "C:\Python27\Lib\site-packages\django\template\base.py" in render
  988.                 bit = node.render_annotated(context)

File "C:\Python27\Lib\site-packages\django\template\base.py" in render_annotated
  955.             return self.render(context)

File "C:\Python27\Lib\site-packages\django\template\base.py" in render
  1039.             output = self.filter_expression.resolve(context)

File "C:\Python27\Lib\site-packages\django\template\base.py" in resolve
  705.                 obj = self.var.resolve(context)

File "C:\Python27\Lib\site-packages\django\template\base.py" in resolve
  846.             value = self._resolve_lookup(context)

File "C:\Python27\Lib\site-packages\django\template\base.py" in _resolve_lookup
  909.                             current = current()

File "C:\Python27\Lib\site-packages\django\forms\forms.py" in non_field_errors
  289.         return self.errors.get(NON_FIELD_ERRORS, self.error_class(error_class='nonfield'))

File "C:\Python27\Lib\site-packages\django\forms\forms.py" in errors
  153.             self.full_clean()

File "C:\Python27\Lib\site-packages\django\forms\forms.py" in full_clean
  363.         self._clean_form()

File "C:\Python27\Lib\site-packages\django\forms\forms.py" in _clean_form
  390.             cleaned_data = self.clean()

File "D:\Other folders\Desktop\Student Job Search\code\opus_jobs_project\listings\forms.py" in clean
  39.         if self.business_address_region and self.business_industry and self.keywords == 'test':

Exception Type: AttributeError at /
Exception Value: 'JobQuickSearchForm' object has no attribute 'business_address_region'

Upvotes: 0

Views: 77

Answers (2)

TomsaJan
TomsaJan

Reputation: 27

I think the problem might be in the clean() function. Try accessing the fields using the cleaned_data dictionary:

def clean(self):
    cleaned_data = super(JobQuickSearchForm, self).clean()
    if cleaned_data['business_address_region'] and cleaned_data['business_industry'] and cleaned_data['keywords'] == '':
        raise ValidationError("You must specify either email or telephone")

I would suggest checking the presence of 'keywords' key in the cleaned_data before comparing to the empty string.

if 'keywords' in cleaned_data ...

I did not test it, but you could give it a try :).

Alternatively you could skip the "super" call, and use self.cleaned_data as shown in the documentation.

Check with https://docs.djangoproject.com/en/1.9/ref/forms/validation/#cleaning-a-specific-field-attribute

Upvotes: 1

bozdoz
bozdoz

Reputation: 12860

I believe you're looking for the cleaned data, which you should be able to access like this:

cleaned_data = super(JobQuickSearchForm, self).clean()
business_address_region = cleaned_data.get('business_address_region')
# etc.

See the example validation here: https://docs.djangoproject.com/en/1.9/ref/forms/validation/#cleaning-and-validating-fields-that-depend-on-each-other

Upvotes: 0

Related Questions