如何在Django中排除表单中的继承字段?

时间:2021-11-15 07:18:52

I have the following form and inherited form:

我有以下表格和继承表格:

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', )

But when I create a UsuarioForm object, why does it show the is_staff field?

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

Update:

If i put self.fields['is_staff'] = None i obtain the next error:

如果我把self.fields ['is_staff'] =无,我会得到下一个错误:

TemplateSyntaxError at /sms/usuarios/add/user/

/ sms / usuarios / add / user /中的TemplateSyntaxError

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

渲染时捕获AttributeError:'NoneType'对象没有属性'label'

3 个解决方案

#1


8  

Maybe you could change the order of this lines:

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

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

You could also do:

你也可以这样做:

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

#2


0  

This is an old question, but starting in Django 1.7.x you can just do the following:

这是一个老问题,但从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')

The exclude portion of Meta is only for excluding ModelForm elements, but any form element can be excluded by setting it to None in the declarations.

Meta的排除部分仅用于排除ModelForm元素,但可以通过在声明中将其设置为None来排除任何表单元素。

From the Django docs on subclassing forms:

从关于子类化表单的Django文档:

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:

通过在子类上将字段名称设置为None,可以声明性地删除从父类继承的Field。例如:

>>> from django import forms

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

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

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

EDIT:

I think the above works in the example given, but it doesn't seem to work for fields that are created due to the Meta on the ModelForm. I think in those cases you need to inherit from the parent's Meta and change the fields given.

我认为上面的例子在给出的示例中起作用,但它似乎不适用于由于ModelForm上的Meta而创建的字段。我认为在这些情况下,您需要继承父级的Meta并更改给定的字段。

#3


-1  

Django form instances store the fields in the 'fields' attribute on the form itself, so in your init, after calling super, you need something like the following:

Django表单实例将字段存储在表单本身的“fields”属性中,因此在init中,在调用super之后,需要类似以下内容:

self.fields['is_staff'] = None

That should solve your problems; setting self.is_staff is just an unrelated variable (the is_staff you set on the class is a class variable not an instance variable).

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

#1


8  

Maybe you could change the order of this lines:

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

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

You could also do:

你也可以这样做:

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

#2


0  

This is an old question, but starting in Django 1.7.x you can just do the following:

这是一个老问题,但从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')

The exclude portion of Meta is only for excluding ModelForm elements, but any form element can be excluded by setting it to None in the declarations.

Meta的排除部分仅用于排除ModelForm元素,但可以通过在声明中将其设置为None来排除任何表单元素。

From the Django docs on subclassing forms:

从关于子类化表单的Django文档:

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:

通过在子类上将字段名称设置为None,可以声明性地删除从父类继承的Field。例如:

>>> from django import forms

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

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

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

EDIT:

I think the above works in the example given, but it doesn't seem to work for fields that are created due to the Meta on the ModelForm. I think in those cases you need to inherit from the parent's Meta and change the fields given.

我认为上面的例子在给出的示例中起作用,但它似乎不适用于由于ModelForm上的Meta而创建的字段。我认为在这些情况下,您需要继承父级的Meta并更改给定的字段。

#3


-1  

Django form instances store the fields in the 'fields' attribute on the form itself, so in your init, after calling super, you need something like the following:

Django表单实例将字段存储在表单本身的“fields”属性中,因此在init中,在调用super之后,需要类似以下内容:

self.fields['is_staff'] = None

That should solve your problems; setting self.is_staff is just an unrelated variable (the is_staff you set on the class is a class variable not an instance variable).

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