2009-03-18 4 views
3

챌린지는 fk 작업으로 그룹화 된 중첩 된 <ul></ul>에서 라디오 선택을 출력합니다.Django Forms, RadioSelect 위젯을 사용하는 ModelChoiceField, 그룹화 (FK로 묶음)

즉.

class Category(models.Model): 
    # ... 

class Task(models.Model): 
    # ... 
    category = models.ForeignKey(Category) 
    # ... 

class ActivityForm(forms.ModelForm): 
    # ... 
    task = forms.ModelChoiceField(
     queryset = Task.objects.all(), 
     widget  = RadioSelectGroupedByFK 
    ) 

forms.py widgets.py

class RadioFieldRendererGroupedByFK(RadioFieldRenderer): 
    """ 
    An object used by RadioSelect to enable customization of radio widgets. 
    """ 
    #def __init__(self, attrs=None): 
     # Need a radio select for each?? Just an Idea. 
     #widgets = (RadioSelect(attrs=attrs), RadioSelect(attrs=attrs)) 
     #super(RadioFieldRendererGroupedByFK, self).__init__(widgets, attrs) 

    def render(self): 
     """Outputs nested <ul> for this set of radio fields.""" 
     return mark_safe(
      #### Somehow the crux of the work happens here? but how to get the 
      #### right context?? 
      u'<ul>\n%s\n</ul>' % u'\n'.join(
       [u'<li>%s</li>' % force_unicode(w) for w in self] 
      ) 
     ) 

class RadioSelectGroupedByFK(forms.RadioSelect): 
    renderer = RadioFieldRendererGroupedByFK 

최고의 감사!

답변

1

itertools.groupby()은 이에 적합합니다. TaskCategory에는 각각 name 속성이 있다고 가정하겠습니다. Django API에 대해서는 알지 못하기 때문에 정렬을 db 쿼리로 옮기고 작업 객체에 액세스하는 방법을 파악하려면 위젯의 속성을 살펴 봐야하지만 기본 공식은 다음과 같습니다.

Breakfast foods: 
* eggs 
* spam 
Dinner foods: 
* spam 
* spam 
* spam 

HTH

:

from itertools import groupby 

# sort first since groupby only groups adjacent items 
tasks.sort(key=lambda task: (task.category.name, task.name)) 

for category, category_tasks in groupby(tasks, key=lambda task: task.category): 
    print '%s:' % category.name 
    for task in category_tasks: 
    print '* %s' % task.name 

이 같은 목록을 인쇄한다

관련 문제