Search code examples
djangodjango-formsmulti-selectmultichoiceitems

Django multiselect choice AttributeError: 'str' object has no attribute 'status_code'


I have defined choices for a category in models.py which is being referenced in forms.py like so:

models.py

class Exp(models.Model):
    CATEGORIES = ( ('Inc', 'Inc'),\
                   ('Hom', 'Hom'),\
                   ('syn', 'Syn'),\
                   ('Was', 'Was')\
                 )

forms.py

class ExpForm(ModelForm):
    category = forms.MultipleChoiceField(choices=Exp.CATEGORIES, widget=forms.CheckboxSelectMultiple())
    class Meta:
        model = Exp

views.py

def view_exp(request):
    if request.method == "POST":
        form = ExpForm(request.POST)
        if form.is_valid():
        ...

The multiselect choice is displayed correctly in the form, but when I select multiple options, the form.is_valid() in views.py is returning false with a AttributeError: 'str' object has no attribute 'status_code error. I understand that I am getting a str instead of an HttpResponse object, but can't figure out how to fix this error. Any help is appreciated.

NOTE: There are other fields in the same form which are of type CharField.

Here is the traceback:

Traceback (most recent call last):
  File "/software/python/python-2.7.3/lib/python2.7/site-packages/django/core/handlers/base.py", line 187, in get_response
    response = middleware_method(request, response)
  File "/software/python/python-2.7.3/lib/python2.7/site-packages/django/middleware/common.py", line 106, in process_response
    if response.status_code == 404:
AttributeError: 'str' object has no attribute 'status_code'

Solution

  • Thanks to y'alls valuable comments and a morning cup of coffee, I took a deep dive into my code. I got it working after fixing the errors. Here is the error that I had in my models.py:

    class Exp(models.Model):
    
        # The first element in each tuple is the actual value to be stored. The second element is the human-readable name for the option.
        CATEGORIES = ( ('Inc', 'Inc'),\
                     ('Clv','Clv'), \
                     ('Dys', 'Dys'), \
                     ('Hom', 'Hom'), \
                     ('Syn','Syn') )
    
        #category = models.CharField(max_length=100, choices=CATEGORIES) <--- culprit
    

    I did not realize that my original definition of category was still lingering around. I commented that out in models.py and it worked as expected!

    Here is my forms.py:

    class ExpForm(ModelForm):
        category = forms.MultipleChoiceField(choices=Exp.CATEGORIES,widget=forms.CheckboxSelectMultiple())
        class Meta:
            model = Exp
    

    Here is my views.py:

    def view_experiment(request):
        if request.method == "POST":
    
            form = ExpForm(request.POST)
            if form.is_valid():
                picked = form.cleaned_data.get('category')
                category = ",".join([str(c) for c in picked])
                return HttpResponse("Multichoiceselect returned {0}".format(category))
            else:
                return "[ERROR] from views: {0}".format(form.errors)
        else:
            form = ExpForm()
        return render(request, 'template.html', {'form': form})
    

    The selected multiple choices is returned as a list of unicode strings. I then converted the list elements to a string and joined them with a comma.

    Also see this