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
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 Category
s, 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']