2011-03-21 56 views
6

我有以下形式和遗传形式:如何在Django的表单中排除继承的字段?

class UsuarioAdminForm(ModelForm): 

    first_name = forms.CharField(label='Nombre', help_text = 'Nombre del usuario', required=True) 
    last_name = forms.CharField(label='Apellidos', help_text = 'Apellidos del usuario', required=True) 
    dni = ESIdentityCardNumberField(help_text = 'DNI del usuario', required=True, widget = forms.TextInput(attrs = {'size': 9})) 
    username = forms.CharField(label='Login', help_text = 'Requerido. 30 caracteres o menos. Letras, números y @/./+/-/_', widget = forms.TextInput(attrs = {'size': 15})) 
    #password = forms.CharField(widget=forms.PasswordInput(attrs = {'size': 12}), label='Contraseña', help_text = 'Contraseña del usuario') 
    email = forms.EmailField(help_text = 'Correo electrónico del usuario', required=True) 
    movil = ESPhoneNumberField(help_text = 'Movil principal del usuario', required=True, widget = forms.TextInput(attrs = {'size': 9 })) 
    is_staff = forms.BooleanField(label = "Administrador", help_text = 'Marque la casilla si desea crear un administrador') 
    tipo_u = forms.ChoiceField(label = 'Tipo de usuario', choices = TipoUsuarios) 
    def clean(self): 
     try: 
      cleaned_data = self.cleaned_data 
      movil = self.cleaned_data['movil'] 
      dni = self.cleaned_data['dni'] 
      email = self.cleaned_data['email'] 
     except: 
      raise forms.ValidationError(u'Todos los campos del Formulario son Obligatorios.') 

     return cleaned_data 

    class Meta: 
     model = Usuario 
     exclude = ('is_active','date_joined', 'last_login', 'user_permissions', 'tipo', 'groups', 'is_superuser',) 


class UsuarioForm(UsuarioAdminForm): 

    is_staff = None 

    def __init__(self, *args, **kwargs): 
     self.is_staff = None 
     super(UsuarioForm,self).__init__(*args, **kwargs) 

    class Meta: 
     model = Usuario 
     exclude = ('is_staff', 'is_active','date_joined', 'last_login', 'user_permissions', 'tipo', 'groups', 'is_superuser', 'password',) 

但是,当我创建一个UsuarioForm对象,为什么它显示is_staff场?

更新:

如果我把self.fields['is_staff'] = None我得到一个错误:

TemplateSyntaxError at /sms/usuarios/add/user/

Caught AttributeError while rendering: 'NoneType' object has no attribute 'label'

+0

它更容易添加然后删除,创建UsuarioForm没有“is_staff”字段和UsuarioAdminForm将只有一个 - 实际的“is_staff = ..”(这是最简单的,将始终工作)。要删除一个类属性,你可以使用del(self.is_staff)(在__init__中),但是这可能会产生额外的后果,因为有MetaClass参与 - 所以尽量不要使用它。 :) – Jerzyk 2011-03-21 13:53:45

回答

7

也许你可以改变这一行的顺序:

def __init__(self, *args, **kwargs): 
    super(UsuarioForm,self).__init__(*args, **kwargs)   
    self.is_staff = None 

你也可以这样做:

def __init__(self, *args, **kwargs): 
    super(UsuarioForm,self).__init__(*args, **kwargs) 
    self.fields.pop('is_staff') 
-1

个Django的表单实例存储在表单本身的“域”属性的字段,所以在您的初始化,调用超之后,你需要像下面这样:

self.fields['is_staff'] = None 

这应该解决您的问题;设置self.is_staff只是一个不相关的变量(您在类中设置的is_staff是一个类变量而不是实例变量)。

+0

如果我把self.fields ['is_staff'] =无我获得下一个错误: TemplateSyntaxError at/sms/usuarios/add/user/ Caught AttributeError while rendering:'NoneType'object has no attribute'标签' – grouser 2011-03-21 15:36:13

+0

当你显示它时,你需要添加逻辑以仅在对象具有它时显示它。如果这只在管理部分中很重要,那么您实际上可以在ModelAdmin类中使用“排除”设置。 http://docs.djangoproject.com/en/1.2/ref/contrib/admin/#django.contrib.admin.ModelAdmin。排除 – 2011-03-21 15:46:36

+0

设置字段为无将使所有的事情最糟糕,如果你需要的话 - 从列表中删除这个(使用'del'),但*不要设置为无*,因为它预计是一个BaseField的实例,而不是会严重崩溃 – Jerzyk 2011-03-21 22:31:56

0

这是一个老问题,但开始在Django 1.7.x你可以执行以下操作:

class UsuarioForm(UsuarioAdminForm): 

    is_staff = None 

    class Meta: 
     model = Usuario 
     exclude = ('is_active', 'date_joined', 'last_login', 'user_permissions', 'tipo', 'groups', 'is_superuser', 'password') 

Metaexclude部分仅用于排除ModelForm的元件,但是任何形式的元件可以被排除在声明中将其设置为None

Django docs on subclassing forms

It’s possible to declaratively remove a Field inherited from a parent class by setting the name of the field to None on the subclass. For example:

>>> from django import forms 

>>> class ParentForm(forms.Form): 
...  name = forms.CharField() 
...  age = forms.IntegerField() 

>>> class ChildForm(ParentForm): 
...  name = None 

>>> ChildForm().fields.keys() 
... ['age'] 

编辑

我认为在例如上面给出的作品,但它似乎并没有为那些由于创建到Meta下地干活在ModelForm上。我认为在这种情况下,您需要继承父母的Meta并更改给出的字段。