我想在表单中将过滤器应用于实例的名称。这是
@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 }}
我尝试使用__unicode__()
扩展Auth.Group
core.models
来覆盖class MyGroup(Auth.Group)
方法,但由于没有等同于AUTH_USER_MODEL
,因此无效}。
但是如何在表单中应用过滤器?
答案 0 :(得分:1)
ModelChoiceField
和ModelMultipleChoiceField
允许您覆盖选择框中的标签。
第一个子类字段类并覆盖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功能。
答案 1 :(得分:0)
另一种解决方案是使用过滤后的值更新此字段中的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
建议的做法的一种黑客行为。