How to group the choices in a Django Select widget?

前端 未结 3 1412
挽巷
挽巷 2020-12-13 10:18

Is it possible to created named choice groups in a Django select (dropdown) widget, when that widget is on a form that is auto-generated from a data Model?

3条回答
  •  [愿得一人]
    2020-12-13 11:10

    You don't need custom iterators. You're gonna need to support that code. Just pass the right choices:

    from django import forms
    from django.db.models import Prefetch
    
    class ProductForm(forms.ModelForm):
        class Meta:
            model = Product
            fields = [...]
    
        def __init__(self, *args, **kwargs):
            super(ProductForm, self).__init__(*args, **kwargs)
            cats = Category.objects \
                .filter(category__isnull=True) \
                .order_by('order') \
                .prefetch_related(Prefetch('subcategories',
                    queryset=Category.objects.order_by('order')))
            self.fields['subcategory'].choices = \
                [("", self.fields['subcategory'].empty_label)] \
                + [(c.name, [
                    (self.fields['subcategory'].prepare_value(sc),
                        self.fields['subcategory'].label_from_instance(sc))
                    for sc in c.subcategories.all()
                ]) for c in cats]
    

    Here,

    class Category(models.Model):
        category = models.ForeignKey('self', null=True, on_delete=models.CASCADE,
            related_name='subcategories', related_query_name='subcategory')
    
    class Product(models.Model):
        subcategory = models.ForeignKey(Category, on_delete=models.CASCADE,
            related_name='products', related_query_name='product')
    

    This same technique can be used to customize a Django admin form. Although, Meta class is not needed in this case.

提交回复
热议问题