2011-03-21 30 views
6

Tengo el siguiente formulario y forma hereditaria:¿Cómo excluyo un campo heredado en un formulario en 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',) 

Pero cuando se crea un objeto UsuarioForm, porqué se muestra el campo is_staff?

Actualización:

si pongo self.fields['is_staff'] = None obtengo el siguiente error:

TemplateSyntaxError at /sms/usuarios/add/user/

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

+0

es más fácil de agregar y eliminar, crear UsuarioForm sin campo "is_staff" y UsuarioAdminForm tendrá solo uno - "is_staff = .." real (esto es más simple y siempre funcionará). para eliminar un atributo de clase puede usar del (self.is_staff) (en __init__) pero esto puede tener consecuencias adicionales ya que hay MetaClasses involucradas, por lo tanto, intente no usarlo. :) – Jerzyk

Respuesta

7

Tal vez usted podría cambiar el orden de estas líneas:

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

También puede hacer:

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

instancias forman Django almacenan los campos en el atributo 'campos' en el propio formulario, por lo que en su init, después de llamar a super, necesita algo como lo siguiente:

self.fields['is_staff'] = None 

Eso debería resolver sus problemas; establecer self.is_staff es solo una variable no relacionada (el is_staff que configura en la clase es una variable de clase, no una variable de instancia).

+0

Si pongo self.fields [ 'is_staff'] = ninguno i obtener el siguiente error: TemplateSyntaxError en/SMS/Usuarios/add/usuario/ Atrapados AttributeError mientras que la prestación: objeto 'NoneType' no tiene atributo ' label ' – grouser

+0

Debe agregar la lógica cuando la muestra para mostrarla solo si el objeto la tiene. Si esto solo es importante en la sección de administración, entonces podría simplemente usar la configuración 'exclude' en la clase ModelAdmin. http://docs.djangoproject.com/en/1.2/ref/contrib/admin/#django.contrib.admin.ModelAdmin.excluir –

+0

campo de configuración en Ninguno hará que todas las cosas peores, si es necesario - eliminar este de la lista (usando 'del'), pero * hacer Nott configurarlo para que ninguno *, ya que se espera que sea una instancia de BaseField y no es chocará mal – Jerzyk

0

Ésta es una cuestión de edad, pero a partir de Django 1.7.x que sólo puede hacer lo siguiente:

class UsuarioForm(UsuarioAdminForm): 

    is_staff = None 

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

La parte exclude de Meta es sólo para excluir ModelForm elementos, pero cualquier elemento de formulario se puede excluir estableciéndolo en None en las declaraciones.

Desde el 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'] 

EDITAR:

creo que las obras mencionadas en el ejemplo dado, pero no parece funcionar para campos que se crean debido a la Meta en el ModelForm. Creo que en esos casos debe heredar de Meta del padre y cambiar los campos dados.

Cuestiones relacionadas