Django SelectMultiple无法显示已保存的选项

时间:2017-08-15 10:15:16

标签: python django django-forms

我在一个带有SelectMultiple的管理表单中,在Django 1.10中有动态填充的选项

这是模型:

class HelpRequest(models.Model):
    name = models.CharField(max_length=32)
    groups = models.TextField(blank=True)

这是我的表格:

class AdminHelpRequestForm(ModelForm):
    def __init__(self, *args, **kwargs):
         super().__init__(*args, **kwargs)
         self.fields['groups'] = forms.MultipleChoiceField(choices=groups_from_ldap,
                                                     widget=SelectMultiple(attrs={'class': 'chosen'}))

    class Meta:
        model = HelpRequest
        fields = ('name', 'groups')

表单在Admin中使用:

@admin.register(HelpRequest)
class HelpRequestAdmin(admin.ModelAdmin):
    form = AdminHelpRequestForm 

SelectMultiple将选项保存在模型中

>>> ar = HelpRequest.objects.get(pk=1)
>>> print(ar.groups)
['mygroup', 'othergroup', 'yetanothergroup']

但是不会在窗口小部件中显示模型实例中保存的选项。

这里有什么问题?

1 个答案:

答案 0 :(得分:0)

在某种程度上反直觉地解决方案是添加自定义清理以创建逗号分隔的选项字符串,然后将该字符串拆分为列表并手动将其设置为初始值:

class AdminHelpRequestForm(ModelForm):
   def __init__(self, *args, **kwargs):
      super().__init__(*args, **kwargs)
      self.fields['groups'] = forms.MultipleChoiceField(choices=groups_from_ldap,
                                              widget=SelectMultiple(attrs={'class': 'chosen'}))

    if self.instance:
        self.initial['groups'] = self.instance.groups.split(',')

class Meta:
    model = HelpRequest
    fields = ('name', 'groups')

def clean_groups(self):
    groups = self.cleaned_data['groups']
    if groups:
        assert isinstance(groups, (list, tuple))
        return str(','.join(groups))
    else:
    return ''

这样可以使管理列表视图中的组简洁易读。

另一个更简洁的可能性是根本没有那个干净的功能,只需使用ast.literal_eval:

import ast

class AdminHelpRequestForm(ModelForm):
   def __init__(self, *args, **kwargs):
      super().__init__(*args, **kwargs)
      self.fields['groups'] = forms.MultipleChoiceField(choices=groups_from_ldap,
                                              widget=SelectMultiple(attrs={'class': 'chosen'}))

    if self.instance.groups:
        self.initial['groups'] = ast.literal.eval(self.instance.groups)

class Meta:
    model = HelpRequest
    fields = ('name', 'groups')