15

There is a multiple checkbox in template, if value contain in render the choice will checked by default. It works well with 1.10.

form.py:

class NewForm(forms.Form):
    project = forms.ModelMultipleChoiceField(
        widget=forms.CheckboxSelectMultiple, 
        queryset=Project.objects.filter(enable=True)
    )

template:

{% for p in form.project %}
<label for="{{ p.id_for_label }}">
    <input type="checkbox" name="{{ p.name }}" id="{{ p.id_for_label }}"
        value="{{ p.choice_value }}"
        {% if p.choice_value|add:"0" in form.project.initial %} checked{% endif %}>
    <p>{{ p.choice_label }}</p>
</label>
{% endfor %}

views.py:

def order_start(request, order_id):
    if request.method == 'POST':
        form = NewForm(request.POST)
        if form.is_valid():
            order.end_time = timezone.now()
            order.save()
            order.project = form.cleaned_data['project']
            order.save()
            return HttpResponsec(order.id)
    else:
        form = NewForm(initial={
            'project': [p.pk for p in order.project.all()],
        })

    return render(request, 'orders/start.html', {'form': form, 'order': orderc})

When I upgrade to Django 1.11, {{ p.name }} and {{ p.choice_value }} return nothing. I know 1.11 has removed choice_value, but how to solve this problem?

1.10 https://docs.djangoproject.com/en/1.10/_modules/django/forms/widgets/
1.11 https://docs.djangoproject.com/en/1.11/_modules/django/forms/widgets/

fen
  • 1,109
  • 9
  • 25

1 Answers1

22

As @L_S 's comments. I debug with dir(form), all value contained in form.project.data here's the correct code:

{% for choice in form.project %}
<labelc for="{{ choice.id_for_label }}">
    <input type="checkbox" name="{{ choice.data.name }}" id="{{ choice.id_for_label }}" 
    value="{{ choice.data.value }}"{% if choice.data.selected %} checked{% endif %}>
    {{ choice.data.label }}
</label>
{% endfor %}
fen
  • 1,109
  • 9
  • 25
  • 1
    though already reflected in your solution, it may be worth noting that in django 1.11 the checked attribute rendered by form widgets now uses HTML5 boolean syntax rather than XHTML’s checked='checked' – Brendan Metcalfe Feb 13 '18 at 13:55
  • 3
    finally got it `{{ choice.data.value }}`. thanks, dude! +1 – Lemayzeur Apr 23 '18 at 06:22
  • We ran into this problem when we upgraded from Django 1.9.5 to 2.x, and the same fix worked for us. – jdg Jan 02 '20 at 18:37