0

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'

2 Answers 2

1

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

Sign up to request clarification or add additional context in comments.

9 Comments

Hi, I am still have trouble with this. I added in your code however if I submit the form it does not raise the error, is this function being called on submit or when the page is being loaded?
One of ways to call this function to ask your form instance is_valid(). in view: form.is_valid() returns True/False. Let's be clear: you want to raise the ValidaionError in case there is nothing filled all three fields?
Yes exactly, ill give you a little bit more info aswell. I am making a search refiner for my website and what I am trying to do right now is stop people from being able to submit the form without having actually entered anything into it. Unfortunately I am having some real trouble with it as I do not know much about forms and more specifically have never used forms with the GET method.
OK. I'll think about it. Do you have to use GET? Why can't you use POST?
Because GET puts it right into the URL which I then extract it from.
|
0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.