4

I have a field (slug) that is "required" in the model, but want to change the field in the ModelAdmin class to be optional. If the user doesn't fill it in, it is automatically filled in by another field (name).

class SomeModel(model.Model):
  name = model.CharField(max_length=255)
  slug = model.SlugField(unique=True, max_length=255)

I tried to do this various ways, such as overriding get_form() within ModelAdmin or using the ModelForm class and specifying the form specifically.

class SomeModelAdmin(admin.ModelAdmin):
    def get_form(self, request, obj=None, **kwargs):
        form = super(self.__class__, self).get_form(request, obj, **kwargs)
        form.slug.required = False
        return form

However, neither solution worked for me. Beyond manually creating the form, is there any other quicker solution?

I have a lot of these forms, and doing it by hand might be tedious and hard to maintain.

4

3 回答 3

5

当我自己遇到同样的问题时,通过谷歌找到了这个页面。以下内容也适用于ModelAdmin

def get_form(self, *args, **kwargs):
    form = super(SomeModelAdmin, self).get_form(*args, **kwargs)
    form.base_fields['slug'].required = False
    return form

从更新创建的后续表单ModelFormMetaclass将具有不需要的slug字段。

这在我的情况下效果更好,我只有一个类,我需要在其中不需要该字段,并且不需要在保存时进行任何数据转换。如果您有很多类,或者需要进行数据转换,GoogleDroid 的解决方案会更好。

于 2012-07-06T16:11:40.657 回答
1

在您的get_form方法中,form.fields['slug'].required应该可以。

但正确的方法是简单地提供一个自定义 ModelForm。

class SomeModelForm(forms.ModelForm):
    slug = forms.CharField(required=False)

class SomeModelAdmin(admin.ModelAdmin):
    form = SomeModelForm

顺便说一句,请不要这样做super(self.__class__, self)。使用时,您应该始终显式命名当前类super,否则从您的继承的任何子类以及依次调用super都会中断。

编辑 form.fields,不是forms.fields

通过说self.__class__,您明确地阻止 Python 处理继承 - 因为它总是引用具体类 - 即继承树的底部。但是,如果您的方法是该树的中间,那么引用具体类super是错误的 - 因为您希望它从您所在的位置调用下一个级别,而不是从底部向上调用。这就是为什么您应该始终命名您所在的班级 - 在这种情况下,super(SomeModelAdmin, self).

于 2011-05-21T18:29:02.740 回答
1

我只是想报告一下,以防其他人发现这很有用。

我从来没有get_form办法做到form.fields['slug'].required,也从来没有弄清楚为什么。但是,我通过创建一个继承自 ModelForm 的新表单解决了我的问题。

我必须在调用父构造函数后重写init () 来设置self.fields['slug'].required = False,然后重写clean_slug()以修改 slug 字段内容,如果需要通过访问self.data['slug'].

希望这可以帮助某人

于 2011-05-26T01:31:16.900 回答