2011-05-21 79 views
3

我有一个在模型中“需要”的字段(slug),但想要将ModelAdmin类中的字段更改为可选。如果用户没有填写,则会自动填入其他字段(名称)。如何在ModelAdmin内动态处理Django中的表单域?

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

我试图这样做的各种方式,如覆盖内的ModelAdmin get_form()或使用的ModelForm类并指定形式具体。

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 

但是,这两种解决方案都不适用于我。除了手动创建表单之外,还有其他更快捷的解决方案吗?

我有很多这些形式,手工操作可能很繁琐而且难以维护。

回答

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)

+0

我使用'forms.fields ['slug']。required'得到了一个'AttributeError'表示字段不是一个有效的属性。提供一个定制的表单是我试图避免的,因为涉及的工作量很大,因为我有很多模型。 另外,我不完全确定为什么'super(self .__ class__,self)'会因为子分类而中断?不应该基于范围来找出Python吗? 感谢您关注此事。 – GoogleDroid 2011-05-21 19:28:45

+0

再次感谢!这是我的一个错字,但在我的代码中是正确的,但仍然无法正常工作。我发现从'get_form'返回的表单的类型是'django.forms.models.ModelFormMetaclass'。 'dir(form)'也没有显示字段属性。 – GoogleDroid 2011-05-21 21:01:46

0

我只是想报告,以防其他人可能会觉得这有用。

我从来没有能够在get_form方法做form.fields['slug'].required并永远不知道为什么。但是,我通过创建一个从ModelForm继承的新窗体来解决我的问题。

我不得不重写INIT()来设置self.fields['slug'].required = False调用父构造后,然后覆盖clean_slug()修改蛞蝓字段内容如果需要通过访问self.data['slug']

希望这可以帮助别人

4

同样的问题摔跤自己,当通过谷歌找到了这个网页。下面也将在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的解决方案会更好。