djangomultiple-choicechoicefield

django Choice list (dynamic choices)


i have a choices list :

CATEGORY_CHOICES = (
("T-shirts", "T-shirts"),
("Hoodies", "Hoodies"),
("Shorts", "Shorts"),

)

but i want to make this list dynamic so i can add and delete choices ,i created a new model Category what i want to do is something like this :

CATEGORY_CHOICES = (
for choice in Category.object.all():
    (choice.category, "choice.category"),
 )

but it doesn't seems to work


Solution

  • In that case, you should not make use of a CharField or some other field with choices, but use a ForeignKey [Django-doc].

    For example:

    class Category(models.Model):
        category = models.CharField(max_length=128, unique=True)
    
        def __str__(self):
            return self.category
    
    class MyModel(models.Model):
        category = models.ForeignKey(Category, on_delete=models.CASCADE)

    If you construct a ModelForm, it will use by default a ModelChoiceField [Django-doc], and the default widget is a dropdown with the Category options.

    If you want to select multiple Categorys, you should use a ManyToManyField [Django-doc]:

    class Category(models.Model):
        category = models.CharField(max_length=128, unique=True)
    
        def __str__(self):
            return self.category
    
    class MyModel(models.Model):
        categories = models.ManyToManyField(Category)

    In a filter, you can then use a ModelMultipleChoiceFilter [readthedocs]:

    class MyModelFilter(django_filters.FilterSet):
        categories = django_filters.ModelMultipleChoiceFilter(
            queryset=Category.objects.all()
        )
        class Meta:
            model = MyModel
            fields = ['categories']

    But normally, without specifying anything that is the default field it will use.

    You can alter the widget to a CheckboxSelectMultiple [Django-doc] to work with a sequence of checkboxes:

    class MyModelFilter(django_filters.FilterSet):
        categories = django_filters.ModelMultipleChoiceFilter(
            queryset=Category.objects.all(),
            widget=forms.CheckboxSelectMultiple()
        )
        class Meta:
            model = MyModel
            fields = ['categories']