Как сделать виджет чекбокс для ModelChoiceField?

Для создания виджета чекбокса для ModelChoiceField в Django, вам потребуется создать собственный кастомный виджет, который будет отображать список вариантов с помощью чекбоксов.

Вот пример кода:

from django import forms

class CheckboxModelChoiceWidget(forms.widgets.CheckboxSelectMultiple):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.attrs['class'] = 'checkbox-model-choice'  # добавляем класс для стилизации виджета

    def render(self, name, value, attrs=None, renderer=None):
        if value is None:
            value = []
        elif not isinstance(value, (list, tuple)):
            value = [value]

        output = []
        if attrs is None:
            attrs = {}
        attrs['name'] = name
        attrs['id'] = attrs.get('id', 'id_%s' % name)
        
        for i, choice in enumerate(self.choices):
            choice_value, choice_label = choice
            checkbox_id = '%s_%s' % (attrs['id'], i)
            checkbox_attrs = attrs.copy()
            checkbox_attrs['value'] = choice_value

            if choice_value in value:
                checkbox_attrs['checked'] = 'checked'
            
            output.append(
                '<label for="%s"><input type="checkbox" id="%s" %s /> %s</label>' % (
                    checkbox_id, checkbox_id, forms.utils.flatatt(checkbox_attrs), choice_label
                )
            )
        return mark_safe('n'.join(output))

Теперь, когда у нас есть собственный виджет, мы можем использовать его в ModelForm. Вам нужно будет создать новый ModelForm и указать виджет для нужного вам поля, используя аргумент widgets.

Пример использования кастомного виджета в ModelForm:

from django import forms
from .models import MyModel

class MyModelForm(forms.ModelForm):
    my_field = forms.ModelChoiceField(
        queryset=MyModel.objects.all(),
        widget=CheckboxModelChoiceWidget()
    )

    class Meta:
        model = MyModel
        fields = ['my_field']

И в вашем шаблоне вы можете просто отобразить форму:

<form method="post" action="{% url 'my_view' %}">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit">Сохранить</button>
</form>

Таким образом, ваша форма будет отображать поле my_field с использованием виджета чекбокса.