Reputation: 503
In my Django project, I have a class with a ManyToManyField:
class ContestCategory(models.Model):
name = models.CharField(max_length=70, blank=False, null=False)
judges = models.ManyToManyField('users.CustomUser', null=True)
I can see after migrating that everything worked fine and the table is created. I made a form to change the judges like this:
class JudgesForm(forms.ModelForm):
class Meta:
model = ContestCategory
fields = ['judges']
def __init__(self, *args, **kwargs):
super(JudgesForm, self).__init__(*args, **kwargs)
In my view, the form appears and correctly displays all the CustomUser objects there are, and shows no error when saving. However, in my post method, when I do this:
class SubmissionCategoriesDetailView(LoginRequiredMixin, DetailView):
model = ContestCategory
template_name = 'reportes/detail_submission_categories.html'
form_class = JudgesForm
def post(self, request, *args, **kwargs):# 1711 5656 2230400 7616
pk_category = kwargs.get('pk')
judges = request.POST.get('judges')
logging.info(str(judges))
return HttpResponseRedirect(reverse('reportes:submission_categories'))
I get in the logs that 'judges' returns the correct Id of my CustomUser but only if I have just one CustomUser selected. Whenever I choose more than one, it only gives me in 'judges' the Id of the last one that was chosen, not of all of them.
Why is this happening? Should I use a different widget than the automatic one or is there something missing from the models? Any help would be appreciated.
Upvotes: 1
Views: 330
Reputation: 476557
Because a request.POST.get(…)
[Django-doc] always returns one value. If you want to return all values, you should make use of request.POST.getlist(…)
[Django-doc]:
from django.shortcuts import redirect
class SubmissionCategoriesDetailView(LoginRequiredMixin, DetailView):
model = ContestCategory
template_name = 'reportes/detail_submission_categories.html'
form_class = JudgesForm
def post(self, request, *args, **kwargs):
pk_category = kwargs.get('pk')
judges = request.POST.getlist('judges')
logging.info(str(judges))
return redirect('reportes:submission_categories')
It is however better to use the form to process the data:
from django.shortcuts import redirect
class SubmissionCategoriesDetailView(LoginRequiredMixin, DetailView):
model = ContestCategory
template_name = 'reportes/detail_submission_categories.html'
form_class = JudgesForm
def post(self, request, *args, **kwargs):
form = JudgesForm(request.POST)
if form.is_valid():
logging.info(str(form.cleaned_data['judges']))
return redirect('reportes:submission_categories')
You might want to take a look at an UpdateView
[Django-doc] to handle the boilerplate logic.
Upvotes: 1