0

我有一个带有字段的模型:

class Movie(models.Model):
    genre = models.CommaSeparatedIntegerField(max_length=100, choices=GENRE_CHOICES, blank=True, default=0)
    lang = models.CommaSeparatedIntegerField(max_length=100, choices=LANG_CHOICES, blank=True, default=0)

我需要从中获取多个选择字段(不是复选框)。

我发现的一种方法是从 ModelAdmin 重新定义表单

class MyMovieAdminForm(forms.ModelForm):
    genre = forms.MultipleChoiceField(choices=GENRE_CHOICES)
    lang = forms.MultipleChoiceField(choices=LANG_CHOICES)

class MovieAdmin(admin.ModelAdmin):
    form = MyMovieAdminForm

admin.site.register(Movie, MovieAdmin)

但是它需要为每个字段重新声明“标签”和“初始”,这不利于 DRY 原则。而且我不明白,如何为每个字段的初始值设置对象的当前值?

而我在手册中发现的其他方式是formfield-overrides。我使用主干中的开发版本,并尝试使用此代码,但它没有将我的选择字段更改为管理界面中的多选:

class MovieAdmin(admin.ModelAdmin):
    formfield_overrides = {
        models.CommaSeparatedIntegerField: {'widget': forms.SelectMultiple},
    }

可能有人知道,定义多个选择字段的最佳方法是什么?谢谢!

4

3 回答 3

1

我没有找到任何将models.CommaSeparatedIntegerField 制作为forms.SelectMultiple 的有效答案。所以我将 models.CommaSeparatedIntegerField 更改为 models.ManyToManyField 并且表单字段变得非常好用!它更适合您需要对该字段进行查询的情况。

于 2009-04-28T08:51:00.987 回答
1

1)从模型中的models.CommaSeparatedIntegerField中删除选择

2) 创建 CommaSeparatedCharField 作为替换

class CommaSeparatedCharField(forms.CharField):
    def to_python(self, value):
        if value in validators.EMPTY_VALUES:
            return u''
        csv = smart_unicode(','.join(value) )
        return csv   

class CommaSeparatedSelectMultiple(forms.SelectMultiple):
    def render(self, *args, **kwargs):
        print args, kwargs
        args_=list(args)
        if type(args_[1])!=list:
            args_[1] = args_[1].split(',')
        return super(CommaSeparatedSelectMultiple, self).render(*args_, **kwargs)

3) 申请

class MyAdmin(admin.ModelAdmin):
    class form(forms.ModelForm):
        def __init__(self, *args, **kwargs):
            super(forms.ModelForm, self).__init__(*args, **kwargs)
            for field_name, choices in [
                ('minutes', [(i,str(i)) for i in range(60)]),
            ]:
                self.fields[field_name] = CommaSeparatedCharField(
                    label=self.fields[field_name].label,
                    initial=self.fields[field_name].initial,
                    widget=forms.CommaSeparatedSelectMultiple(choices=choices)
                )

在 1.2 主干上工作得很好

于 2010-04-20T08:16:08.837 回答
0

我将以下内容用于有点 DRYer 的表单操作,它适用于 1.0。它很冗长,但它有效。

class MyMovieAdminForm(forms.ModelForm):
    ## Meta, etc

    def __init__(self, *args, **kwargs):
        super(MyMovieAdminForm, self).__init__(*args, **kwargs)
        self.fields["genre"].widget = forms.SelectMultiple(choices=foo)
        self.fields["genre"].initial = self.instance.genre
        # Doesn't require redefining label, etc.
于 2009-04-07T13:42:13.403 回答