1

I want to add a multiple choice field to my project app. This field should allow the user for select more than one choice. But I get an error. Before I added the multiple choice field, this part did not give any error. Where is my mistake?

my views.py

def project_new(request):
if request.method == 'POST':
    form = ProjectForm(request.POST)
    if form.is_valid():
        project = Project()
       ...
        project.lang_choices = form.cleaned_data['select_lang']
        project.save()
        return redirect('projects')
else:
    form = ProjectForm()


  return render(request, 'blog/project_new.html', {'form': form})

@login_required(login_url='/login/')
def project_details(request, pk):
    project = get_object_or_404(Project, pk=pk)
    return render(request, 'blog/project_detail.html', {'project': project})

my models.py

class ProgrammingLanguage(models.Model):
name = models.CharField(max_length=100)

def __str__(self):
    return self.name
class Project(models.Model):
        ...
        select_langs = models.ManyToManyField(ProgrammingLanguage)
        ...
        slug = models.UUIDField(default=uuid.uuid4)
    ...

forms.py

class ProjectForm(forms.Form):
...
select_lang = forms.ChoiceField(
    label='diller: ',
    widget=forms.CheckboxSelectMultiple()
)

def __init__(self, *args, **kwargs):
    super(ProjectForm, self).__init__(args, kwargs)



       self.fields['select_lang'].choices = [(l.id, l.name) for l in ProgrammingLanguage.objects.all()]


class Meta:
    model = Project
    fields = (
        'first_name', 'last_name', 'email', 'project_name', 'project_description', 'project_notes', 'select_langs')

And this is my traceback

Internal Server Error: /project/new/
Traceback (most recent call last):
  File "/home/eda/.local/lib/python2.7/site-packages/django/core/handlers/exception.py", line 41, in inner
    response = get_response(request)
  File "/home/eda/.local/lib/python2.7/site-packages/django/core/handlers/base.py", line 187, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/home/eda/.local/lib/python2.7/site-packages/django/core/handlers/base.py", line 185, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/home/eda/.local/lib/python2.7/site-packages/django/contrib/auth/decorators.py", line 23, in _wrapped_view
    return view_func(request, *args, **kwargs)
  File "/home/eda/staj_defteri/project/views.py", line 16, in project_new
    if form.is_valid():
  File "/home/eda/.local/lib/python2.7/site-packages/django/forms/forms.py", line 183, in is_valid
    return self.is_bound and not self.errors
  File "/home/eda/.local/lib/python2.7/site-packages/django/forms/forms.py", line 175, in errors
    self.full_clean()
  File "/home/eda/.local/lib/python2.7/site-packages/django/forms/forms.py", line 384, in full_clean
    self._clean_fields()
  File "/home/eda/.local/lib/python2.7/site-packages/django/forms/forms.py", line 396, in _clean_fields
    value = field.widget.value_from_datadict(self.data, self.files, self.add_prefix(name))
  File "/home/eda/.local/lib/python2.7/site-packages/django/forms/widgets.py", line 240, in value_from_datadict
    return data.get(name)
AttributeError: 'tuple' object has no attribute 'get'
[17/Sep/2018 08:19:35] "POST /project/new/ HTTP/1.1" 500 98194
3
  • 2
    Please show the full traceback. Where is the error happening? Commented Sep 17, 2018 at 8:13
  • 2
    Add the traceback to your question.There's no get method call in the code you've included here. Commented Sep 17, 2018 at 8:14
  • You call the __init__ with args and kwargs, not *args and **kwargs. Commented Sep 17, 2018 at 8:22

1 Answer 1

4

The error is probably the fact that you call the super(ProjectForm, self).__init__ with args, and kwargs as two parameters, not with sequence unpacking and dictionary unpacking, like:

def __init__(self, *args, **kwargs):
    super(ProjectForm, self).__init__(*args, **kwargs)
    self.fields['select_lang'].choices = [
        (l.id, l.name) for l in ProgrammingLanguage.objects.all()
    ]

In case you call it with args, etc. the first parameter will contain a (possibly empty) tuple as data parameter. If you then later aim to process the data, it will fail to do so.

That being said, I do not understand why you make it a forms.ChoiceField here. By default Django will pick a ModelMultipleChoiceField [Django-doc] field, and also take by default the entire collection of ProgrammingLanguage onbjects.

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

2 Comments

I have just one more question. I want to display that the user's choices in my project details page. How can I do it in my HTML page?
You can iterate over the programming languages with {% for lang in project.select_langs %} (end with {% endfor %}), and thus in the loop for example print {{ lang }}.

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.