2010-09-17 2 views
2

У меня есть форму с ModelMultipleChoiceField в список категорий. Я хотел бы сгруппировать категории, используя поле Category.group.Как добавить optgroups в django ModelMultipleChoiceField?

Я думал, что, изменив поле. choices в функции инициализации он будет делать трюк

class CategoriesField(forms.ModelMultipleChoiceField): 
    def __init__(self, queryset, **kwargs): 
     super(forms.ModelMultipleChoiceField, self).__init__(queryset, **kwargs) 
     self.queryset = queryset.select_related() 
     self.to_field_name=None 

     group = None 
     list = [] 
     self.choices = [] 

     for category in queryset: 
      if not group: 
       group = category.group 

      if group != category.group: 
       self.choices.append((group.title, list)) 
       group = category.group 
       list = [(category.id, category.name)] 
      else: 
       list.append((category.id, category.name)) 
     try: 
      self.choices.append((group.title, list)) 
     except: 
      pass 

Но ModelChoiceIterator еще стереть self.choices данные, которые установлены в функции __init__.

Как я могу это сделать правильно?

ответ

0

На самом деле она работает, как я только объяснить, но не забывайте, что часть:

class ProfilForm(ModelForm): 
    categories = CategoriesField(queryset=Category.objects.all().order_by('group'), label=_(u'Catégories')) 
0

Я нашел этот вопрос/ответ полезным, но изменил код много. Проблема с вышеуказанным кодом заключается в том, что он генерирует только один список, а затем кэшируется (набор запросов используется только один раз). Мой код предназначен для объектов «Article», которые упорядочены по «профилю» (как автор), но каждый должен иметь возможность модифицировать его для их использования. Он каждый раз использует новый запрос, поэтому он обновляется без перезагрузки (если вы не пропустили cache_choices=True до ArticleMultipleChoiceField, а затем его кешировали).

class ArticleChoiceIterator(forms.models.ModelChoiceIterator): 
    def __iter__(self): 
     if self.field.empty_label is not None: 
      yield ("", self.field.empty_label) 
     if self.field.cache_choices: 
      if self.field.choice_cache is None: 
       last_profile = None 
       self.field.choice_cache = [] 
       for article in self.queryset.all(): 
        if last_profile != article.profile: 
         last_profile = article.profile 
         article_list = [] 
         self.field.choice_cache.append((article.profile.name, article_list)) 
        article_list.append(self.choice(article)) 
      for choice in self.field.choice_cache: 
       yield choice 
     else: 
      last_profile = None 
      article_choices = [] 
      for article in self.queryset.all(): 
       if last_profile != article.profile: 
        if article_choices: 
         yield (getattr(last_profile, 'name', ''), article_choices) 
        last_profile = article.profile 
        article_choices = [] 
       article_choices.append(self.choice(article)) 
      if article_choices: 
       yield (getattr(last_profile, 'name', ''), article_choices) 


class ArticleMultipleChoiceField(forms.ModelMultipleChoiceField): 
    # make sure queryset is ordered by profile first! 
    def __init__(self, queryset, **kwargs): 
     super(ArticleMultipleChoiceField, self).__init__(queryset, **kwargs) 
     self.queryset = queryset.select_related('profile') 
     self._choices = ArticleChoiceIterator(self) 


class PackageForm(forms.ModelForm): 
    articles = ArticleMultipleChoiceField(
     queryset=Article.objects.order_by('profile__name', 'title') 
    ) 
Смежные вопросы