在template / formset中对ManyToMany值进行分组

时间:2015-04-22 21:40:14

标签: django django-templates

我有一个内容分析应用程序,其中标记了注释。每个标签都有“内涵”。因为多个标签可以应用于多个注释,所以我在Tags模型和Comments模型之间建立了多对多关系。标签模型具有内涵的字段。除了这个可用性功能外,我还有一个工作表单。

来自models.py

class Tags( models.Model ):

    CONNOTATION_CHOICES = ( ( '+', 'Positive' ), ( '-', 'Negative' ), ( '?', 'Ambivalent' ), ( '=', 'Informational' ), )

    tag = models.CharField( max_length = 40, blank = False )
    description = models.TextField( blank = True )
    connotation = models.CharField( max_length = 1, choices = CONNOTATION_CHOICES, blank = False )

    def __str__( self ):
        return "".join(( self.connotation, self.tag ))


class Comments( models.Model ):

    comment     = models.TextField( blank = False )
    tags        = models.ManyToManyField( Tags )
    coder       = models.ForeignKey( User, null = True, blank = True )
    coder_comment = models.TextField( blank = True )

    def __str__( self ):
        return "{0} [{1}]".format( self.comment[:40], self.coder ) 

来自forms.py

class CommentForm( forms.ModelForm ):
    class Meta:
        model = Comments
        fields = [ 
                'tags',
                'comment',
                'coder',
                'coder_comment',
                ]
        widgets = {
                'tags': forms.CheckboxSelectMultiple(),
                }

来自views.py

def edit( request ):
    FormSet = modelformset_factory( Comments, form=CommentForm, extra=0 )

    # Form not submitted, need to generate a blank one
    if request.method != 'POST':
        query = Comments.objects.all()

        group_by = 25
        paginator = Paginator( query, group_by )

        try:
            page = request.GET.get( 'page' )
            comments = paginator.page( page )
        except ( PageNotAnInteger, KeyError ):
            comments = paginator.page( 1 )
        except EmptyPage:
            comments = paginator.page( paginator.num_pages )

        page_query = query.filter( id__in = [ comment.id for comment in comments ] )
        formset = FormSet( queryset = page_query )

        context = { 'comments': comments, 'formset': formset }
        return render( request, 'commoncore/edit.html', context )

    # Submitted, so validate and process data
    else:
        # . . .

我的问题:在模板中,我想按内涵对标签进行分组。像

这样的东西
{% for form in formset %}
    <td>
    {% for t in form.tags %}
        {% if t.connotation == "+" %}{{ t.tag }}{% endif %}
    {% endfor %}
    </td>
    <td>
    {% for t in form.tags %}
        {% if t.connotation == "-" %}{{ t.tag }}{% endif %}
    {% endfor %}
    </td>
    <td>
    {% for t in form.tags %}
        {% if t.connotation == "?" %}{{ t.tag }}{% endif %}
    {% endfor %}
    </td>
    <td>
    {% for t in form.tags %}
        {% if t.connotation == "=" %}{{ t.tag }}{% endif %}
    {% endfor %}
    </td>
{% endfor %}

但这不起作用,因为t显然实际上无法访问Tag的字段 - 或者至少我无法发现它们被隐藏的位置。是否有必要提供在views.py中过滤的多个标记列表?或者,我可以根据标签的__str__()表示编写模板过滤器,但这看起来有点笨拙。还有更好的方法吗?

1 个答案:

答案 0 :(得分:0)

在尝试regoupcurry以及其他各种方法后,我没有成功,最后使用了以下硬编码方法,而不是类似于foreach的方法。在forms.py

class CommentCodesForm( forms.ModelForm ):
    pos_tags = forms.ModelMultipleChoiceField(
            queryset = Tags.objects.all().filter( connotation = '+' ),
            widget = forms.CheckboxSelectMultiple()
            )
    neg_tags = forms.ModelMultipleChoiceField(
            queryset = Tags.objects.all().filter( connotation = '-' ),
            widget = forms.CheckboxSelectMultiple()
            )
    amb_tags = forms.ModelMultipleChoiceField(
            queryset = Tags.objects.all().filter( connotation = '?' ),                                                    
            widget = forms.CheckboxSelectMultiple()
            )
    info_tags = forms.ModelMultipleChoiceField(
            queryset = Tags.objects.all().filter( connotation = '=' ),
            widget = forms.CheckboxSelectMultiple()
            )

    class Meta:
        model = CommentCodes
        fields = [
                'pos_tags',
                'neg_tags',
                'amb_tags',
                'info_tags',
...

在模板中我使用了普通的{{ pos_tags }}符号。