覆盖模型管理员中ForeignKey字段选项时的ValueError

时间:2013-02-06 13:00:58

标签: django forms admin

我正在覆盖模型的管理形式,以修改choices字段的ForeignKey。 在管理表单中选择一个选项并保存时,我会得到一个ValueError

Cannot assign "u'6'": "MyModel1.mymodel2" must be a "MyModel2" instance

其中6是所选选项的ID。

新的choices构建为((<choice_1_id>, <choice_1_label>), (<choice_2_id>, <choice_2_label>),...),我为渲染的选择窗口小部件获取相同的html,就像我不修改choices一样(除了课程的顺序) )。

如果我在self.fields['mymodel2'] = forms.ChoiceField(choices=choices)中发表评论MyModel1AdminForm.__init__(),我就不会收到错误...

有人可以帮忙吗?

models.py

class MyModel1(models.Model):
    mymodel2 = ForeignKey(MyModel2)
    # more fields...

admin.py

class MyModel1AdminForm(forms.ModelForm):

    class Meta:
        model = MyModel1

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

        # create choices with ((<choice_1_id>, <choice_1_label>), (<choice_2_id>, <choice_2_label>),...)

        self.fields['mymodel2'] = forms.ChoiceField(choices=choices, widget=SelectWithDisabled) # http://djangosnippets.org/snippets/2453/


class MyModel1Admin(admin.ModelAdmin):
    form = MyModel1AdminForm
my_site.register(MyModel1, MyModel1Admin)

3 个答案:

答案 0 :(得分:1)

mymodel2是外键字段。如果要更改选项而不是添加自定义选项,则需要提供查询集:

self.fields['mymodel2'].queryset = MyModel2.objects.all()

答案 1 :(得分:0)

如果您需要手动构建类似

的选项
choices = MyModel2.objects.values_list('pk', 'title')

应使用标准ChoiceField,其中title是您要用作标签/详细名称的模型字段。


查看您使用values_list的代码段将无效,因此您可以回退到列表理解:

[(c.pk, {'label': c.title, 'disabled': False}) for c in MyModel2.objects.all()]

虽然您显然需要更多逻辑来决定是启用还是禁用选项。

答案 2 :(得分:0)

我最终覆盖了ModelChoiceField

class MyModelChoiceField(forms.ModelChoiceField):
    def label_from_instance(self, obj):
        level = getattr(obj, obj._mptt_meta.level_attr)
        return {'label': obj.name), 'disabled': check_disabled(obj)}