如何在表单中的 Django Auth.Group 实例上覆盖 __unicode__?

How to override __unicode__ on Django Auth.Group instance in form?

我想在表单中对组实例的名称应用过滤器。这里是

我的过滤器

@register.filter(name='prettify_group')
def prettify_group(group):
    try:
        group = group.name
    except TypeError:
        group = group

    if group == 'sysadmin':
        return _('Sysadmin')
    elif group == 'ceo':
        return _("Chef d'entreprise")
    else:
        return group

我的表格

class InternalActorForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        if 'instance' in kwargs and kwargs['instance'] is not None:
            initial['groups'] = [g.pk for g in User.objects.get(username=kwargs['instance'].username).groups.all()]
        super(InternalActorForm, self).__init__(*args, **kwargs)

我的视图模板

这符合预期

{% if groups %}
    <dt>{% trans 'Groupe (permissions)' %}</dt>
    {% for group in groups %}
        <dd class="inline-item">
        {{ field=group|prettify_group }}
        </dd>
    {% endfor %}
{% endif %}

我的编辑模板

    {{ form }}

问题

我试图通过将 core.models 中的 Auth.Group 扩展为 class MyGroup(Auth.Group) 来覆盖 __unicode__() 方法,但它没有用,因为没有等同于 AUTH_USER_MODEL.

但是如何在表单中应用过滤器?

ModelChoiceFieldModelMultipleChoiceField 允许您覆盖 select 框中的标签。

第一个子class字段class并覆盖label_from_instance方法。

class GroupMultipleChoiceField(forms.ModelMultipleChoiceField):

    def label_from_instance(self, obj):
        return prettify_group(obj)

现在在您的表单中使用此字段而不是标准 ModelMultipleChoiceField

class InternalActorForm(forms.ModelForm):

    groups = GroupMultipleChoiceField(queryset=Group.objects.all())

    def __init__(self, *args, **kwargs):
        ...

这是 documented Django 功能。

另一种解决方案是使用过滤后的值从该字段更新 choices 列表:

def __init__(self, *args, **kwargs):
    super(InternalActorForm, self).__init__(*args, **kwargs)
    self.fields['groups'].choices = [(gid, filters.prettify_group(name)) for gid, name in self.fields['groups'].choices]

但我想这是按照 @catavaran 建议的方式进行操作的一种骇人听闻的方式。