Steve H
Steve H

Reputation: 51

Django form object has no attribute 'get'

Hi I'm having an error when I try load a form template into the html. When it loads the error I'm getting back is:

'CleanUpSelectForm' object has no attribute 'get'

The section of HTML that fails is here:

        <form id="feedback_select" class='hidden' action="{% url 'clean_feedback' %}" method="post" autocomplete="off">
        {% csrf_token %}
        {% for field in forms %}
            {% include "snippets/simple_form_row.html" with label=field.label_tag val=field|addcss:'profile_field' %}
        {% endfor %}
        <div style="text-align:right" class="top-padding">
            <button class="mainButton get_feedback">show feedback</button>
        </div>
        <hr class="fade-in-out-right">
    </form>

The form class is of the following:

class CleanUpSelectForm(forms.Form):

def __init__(self, company=None):
    super(CleanUpSelectForm,self).__init__(self)

    self.FILTER_TRANSLATIONS = dict(
        test_cycle='test_cycle_id',
        app_version='question__group__app_id',
        app_reference='question__group__app__app_reference_id',
    )

    self.NULL_CHOICE = [('', 'Please Select')]
    self.TC_CHOICES = models.TestCycle.objects.filter(
        id__in=models.Feedback.objects.filter(done=False).values_list('test_cycle_id',flat=True)
    )

    self.RELATED_QUESTIONS = models.Question.objects.filter(
        id__in=models.Feedback.objects.filter(done=False).values_list('question_id',flat=True))

    self.RELATED_QUESTION_GROUPS = models.QuestionGroup.objects.filter(
        id__in=self.RELATED_QUESTIONS.values_list('group_id', flat=True))

    self.RELATED_APPS = models.App.objects.filter(
        id__in=self.RELATED_QUESTION_GROUPS.values_list('app_id', flat=True))

    self.APP_CHOICES = models.AppReference.objects.filter(
        id__in=self.RELATED_APPS.values_list('app_reference_id', flat=True)
    ).values_list('id','name')

    if company:
        self.TC_CHOICES = self.TC_CHOICES.filter(company=company).values_list('id','name')
    else:
        self.TC_CHOICES = self.TC_CHOICES.values_list('id','name')

    self.test_cycle = forms.ChoiceField(choices=self.NULL_CHOICE+list(self.TC_CHOICES), required=False)
    self.app_reference = forms.ChoiceField(choices=self.NULL_CHOICE+list(self.APP_CHOICES), required=False,
                                      widget=forms.Select(attrs={'appref':
                                                                     'true'})
                                      )
    self.app_version = forms.ChoiceField(choices=self.RELATED_APPS.values_list('id',
                                                                     'version'), required=False,
                                      widget=forms.Select(attrs={
                                          'form_display': 'none'})
                                      )
    self.fields['test_cycle'] = self.test_cycle

and it's called from here within the .py file

    context.update({'forms': CleanUpSelectForm()})

If I remove the self.fields['test_cycle'] = self.test_cycle line and replace with self.fields = [], the error doesn't occur but obviously the template is empty. So I'm looking to find the correct was to feed the form fields in without any errors. Once again thanks for the help as I'm pretty stuck!

EDIT - stack trace:

    Environment:


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

Django Version: 1.7.4
Python Version: 2.7.6
Installed Applications:
('django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.sites',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'django.contrib.humanize',
 'nested_inline',
 'django.contrib.admin',
 'tccore')
Installed Middleware:
('django.middleware.common.CommonMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware',
 'django.contrib.auth.middleware.SessionAuthenticationMiddleware')


Template error:
In template /Users/stephenharrison/Documents/Repo/TestRocket/tccore/templates/tccore/clean_up.html, error at line 18
   'CleanUpSelectForm' object has no attribute 'get'
   8 : {% endblock js %}


   9 : {% block navs %}


   10 : <div class="see_layout top_right_menu linked " data-href="{% url 'groundcontrol' %}">Ground control</div>


   11 : {% endblock %}


   12 : 


   13 : {% block content %}


   14 :     {%  if forms %}


   15 :         <form id="feedback_select" class='hidden' action="{% url 'clean_feedback' %}" method="post" autocomplete="off">


   16 :             {% csrf_token %}


   17 :             {% for field in forms %}


   18 :                  {% include "snippets/simple_form_row.html" with label=field.label_tag val=field|addcss:'profile_field' %} 


   19 :             {% endfor %}


   20 :             <div style="text-align:right" class="top-padding">


   21 :                 <button class="mainButton get_feedback">show feedback</button>


   22 :             </div>


   23 :             <hr class="fade-in-out-right">


   24 :         </form>


   25 :     {% endif %}


   26 :     <div id="counter"></div>


   27 :     <div id="cleaner" class="hidden">


   28 :         <div id="cleaner_headers">


Traceback:
File "/Library/Python/2.7/site-packages/django/core/handlers/base.py" in get_response
  111.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Library/Python/2.7/site-packages/django/contrib/auth/decorators.py" in _wrapped_view
  21.                 return view_func(request, *args, **kwargs)
File "/Users/stephenharrison/Documents/Repo/TestRocket/tccore/views/clean_up.py" in clean_feedback
  167.     return render(request, template, context)
File "/Library/Python/2.7/site-packages/django/shortcuts.py" in render
  50.     return HttpResponse(loader.render_to_string(*args, **kwargs),
File "/Library/Python/2.7/site-packages/django/template/loader.py" in render_to_string
  178.         return t.render(context_instance)
File "/Library/Python/2.7/site-packages/django/template/base.py" in render
  148.             return self._render(context)
File "/Library/Python/2.7/site-packages/django/template/base.py" in _render
  142.         return self.nodelist.render(context)
File "/Library/Python/2.7/site-packages/django/template/base.py" in render
  844.                 bit = self.render_node(node, context)
File "/Library/Python/2.7/site-packages/django/template/debug.py" in render_node
  80.             return node.render(context)
File "/Library/Python/2.7/site-packages/django/template/loader_tags.py" in render
  126.         return compiled_parent._render(context)
File "/Library/Python/2.7/site-packages/django/template/base.py" in _render
  142.         return self.nodelist.render(context)
File "/Library/Python/2.7/site-packages/django/template/base.py" in render
  844.                 bit = self.render_node(node, context)
File "/Library/Python/2.7/site-packages/django/template/debug.py" in render_node
  80.             return node.render(context)
File "/Library/Python/2.7/site-packages/django/template/defaulttags.py" in render
  38.         output = self.nodelist.render(context)
File "/Library/Python/2.7/site-packages/django/template/base.py" in render
  844.                 bit = self.render_node(node, context)
File "/Library/Python/2.7/site-packages/django/template/debug.py" in render_node
  80.             return node.render(context)
File "/Library/Python/2.7/site-packages/django/template/loader_tags.py" in render
  65.                 result = block.nodelist.render(context)
File "/Library/Python/2.7/site-packages/django/template/base.py" in render
  844.                 bit = self.render_node(node, context)
File "/Library/Python/2.7/site-packages/django/template/debug.py" in render_node
  80.             return node.render(context)
File "/Library/Python/2.7/site-packages/django/template/defaulttags.py" in render
  312.                 return nodelist.render(context)
File "/Library/Python/2.7/site-packages/django/template/base.py" in render
  844.                 bit = self.render_node(node, context)
File "/Library/Python/2.7/site-packages/django/template/debug.py" in render_node
  80.             return node.render(context)
File "/Library/Python/2.7/site-packages/django/template/defaulttags.py" in render
  201.                             nodelist.append(node.render(context))
File "/Library/Python/2.7/site-packages/django/template/loader_tags.py" in render
  145.                 for name, var in six.iteritems(self.extra_context)
File "/Library/Python/2.7/site-packages/django/template/loader_tags.py" in <dictcomp>
  145.                 for name, var in six.iteritems(self.extra_context)
File "/Library/Python/2.7/site-packages/django/template/base.py" in resolve
  624.                 new_obj = func(obj, *arg_vals)
File "/Users/stephenharrison/Documents/Repo/TestRocket/tccore/templatetags/tccore_extras.py" in addcss
  74.     return field.as_widget(attrs={"class": ' '.join([field.field.widget.attrs.get('class',''), css])})
File "/Library/Python/2.7/site-packages/django/forms/forms.py" in as_widget
  560.         return force_text(widget.render(name, self.value(), attrs=attrs))
File "/Library/Python/2.7/site-packages/django/forms/forms.py" in value
  601.                 self.data, self.form.initial.get(self.name, self.field.initial)
File "/Library/Python/2.7/site-packages/django/forms/forms.py" in data
  583.         return self.field.widget.value_from_datadict(self.form.data, self.form.files, self.html_name)
File "/Library/Python/2.7/site-packages/django/forms/widgets.py" in value_from_datadict
  228.         return data.get(name, None)

Exception Type: AttributeError at /clean_feedback/
Exception Value: 'CleanUpSelectForm' object has no attribute 'get'
    enter code here

Upvotes: 5

Views: 7474

Answers (2)

Senya Sumkin
Senya Sumkin

Reputation: 211

The cause of the problem here:

super(CleanUpSelectForm,self).__init__(self)

You don't need pass self when use super(..). So it should be:

super(CleanUpSelectForm,self).__init__()

Upvotes: 21

dhke
dhke

Reputation: 15398

It is not (directly) supported to add django form fields in the form's __init__().

Form fields are supposed to be declared as class attributes. Django (actually django.forms.forms.DeclarativeFieldsMetaclass) picks up the form fields from the class attributes in __new__(). Form fields are transformed before object creation so if you bypass that mechanism, the behavior is essentially undefined.

If you need dynamic choices, use a callable for the choices parameter:

NULL_CHOICE = [...]

def get_tc_choices():
    return NULL_CHOICE + list(models.TestCycle.objects.filter(
        id__in=models.Feedback.objects.filter(done=False).values_list('test_cycle_id',flat=True)
    ))

[...]
class CleanUpSelectForm(forms.Form):
    test_cycle = forms.ChoiceField(choices=get_tc_choices, required=False)

Upvotes: 0

Related Questions