About Multiple Choice Fields without Many-to-Many Relations

You can have a multiple choice selection in your models by combining a models.JSONField and custom form with a forms.MultipleChoiceField in the form.

configuration/models.py:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
from django.db import models

class Configuration(models.Model):
    SETTING_CHOICES = [
        ("ads", "Display ads"),
        ("maintenance", "Show maintenance notification"),
        ("announcement", "Show announcement"),
    ]
    settings = models.JSONField(
        verbose_name=_("Settings"), blank=True, null=True,
    )

    class Meta:
        verbose_name = "Website Configuration"
        verbose_name_plural = "Website Configurations"

    def __str__(self):
        return "Configuration"

configuration/admin.py:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
from django import forms
from django.contrib import admin
from .models import Configuration

class ConfigurationForm(forms.ModelForm):
    settings = forms.MultipleChoiceField(
        label=Configuration._meta.get_field("settings").verbose_name,
        choices=Configuration.SETTING_CHOICES,
        required=not Configuration._meta.get_field("settings").blank,
        widget=forms.CheckboxSelectMultiple(),
    )
    class Meta:
        model = Configuration
        fields = "__all__"

@admin.register(Configuration)
class ConfigurationAdmin(admin.ModelAdmin):
    form = ConfigurationForm
    list_display = ["__str__"]
    fields = ["settings"]

Tips and Tricks Development Django 5.x Django 4.2 Django 3.2