Cambiar un campo de formulario de Django a un campo oculto


128

Tengo un formulario Django con a RegexField, que es muy similar a un campo de entrada de texto normal.

Desde mi punto de vista, bajo ciertas condiciones quiero ocultarlo al usuario e intentar mantener el formulario lo más similar posible. ¿Cuál es la mejor manera de convertir este campo en un HiddenInputcampo?

Sé que puedo establecer atributos en el campo con:

form['fieldname'].field.widget.attr['readonly'] = 'readonly'

Y puedo establecer el valor inicial deseado con:

form.initial['fieldname'] = 'mydesiredvalue'

Sin embargo, eso no cambiará la forma del widget.

¿Cuál es la mejor / más "django-y" / menos "hacky" para hacer de este campo un <input type="hidden">campo?

Respuestas:


169

Si tiene una plantilla y vista personalizadas, puede excluir el campo y utilizarlo {{ modelform.instance.field }}para obtener el valor.

También puede preferir usar en la vista:

form.fields['field_name'].widget = forms.HiddenInput()

pero no estoy seguro de que protegerá el método de guardar en la publicación.

Espero eso ayude.


1
&quot;&quot; is not a valid value for a primary key.Termino con un método is_valid después de usar esta solución.
Jens Timmerman

Suena extraño. Creo que está relacionado con algo más, ¿estás mostrando como HiddenInput la clave principal de los objetos que estás creando? Si es así, no deberías.
christophe31

Tal vez esto sea evidente, pero deberá importar los formularios antes de que esto funcione. from django import forms
teewuane

2
en 1.7 use esta sintaxis: hidden_field_name = forms.CharField(label='reset', max_length=256, widget=forms.HiddenInput())donde la clave es la sintaxis de widget más reciente al final. Ajusta tus necesidades.
Marc

196

Esto también puede ser útil: {{ form.field.as_hidden }}


3
Esta es la mejor respuesta en mi humilde opinión. Siempre he odiado usar mi código Python "controlador" para determinar la visualización de un campo de formulario.
trpt4him

A menudo hago plantillas genéricas de formularios con formas crujientes. Si usa formas crujientes o muestra campos en un bucle simple porque desea que su estructura de formulario en su clase de formulario, el widget que sobrescribe en el formulario es la buena manera de hacerlo. Pero si administra el procesamiento de su formulario en su plantilla, esta solución es mucho más clara / limpia.
christophe31

Vale la pena señalar que esto parece borrar cualquier clase que haya aplicado al campo de antemano ...
John Aaron

59

una opción que funcionó para mí, defina el campo en la forma original como:

forms.CharField(widget = forms.HiddenInput(), required = False)

luego, cuando lo anula en la nueva Clase, mantendrá su lugar.


45

En primer lugar, si no desea que el usuario modifique los datos, entonces parece más claro simplemente excluir el campo. Incluirlo como un campo oculto solo agrega más datos para enviar a través del cable e invita a un usuario malintencionado a modificarlo cuando no lo desee. Si tiene una buena razón para incluir el campo pero ocultarlo, puede pasar una palabra clave arg al constructor de la forma de modelo. Algo como esto quizás:

class MyModelForm(forms.ModelForm):
    class Meta:
        model = MyModel
    def __init__(self, *args, **kwargs):
        from django.forms.widgets import HiddenInput
        hide_condition = kwargs.pop('hide_condition',None)
        super(MyModelForm, self).__init__(*args, **kwargs)
        if hide_condition:
            self.fields['fieldname'].widget = HiddenInput()
            # or alternately:  del self.fields['fieldname']  to remove it from the form altogether.

Entonces en tu opinión:

form = MyModelForm(hide_condition=True)

Prefiero este enfoque para modificar las partes internas del modelo en la vista, pero es cuestión de gustos.


11
solo consejo simple, kwargs.pop ('hide_condition', False) en lugar de kwargs ['hide_condition']. manejará el caso sin argumentos, tendrá un valor predeterminado y eliminará al mismo tiempo.
christophe31

2
gracias por el dato, christophe31. He actualizado con su sugerencia, ya que hace que el código sea mucho más claro.
rych

1
¿Es posible ocultar el campo con este enfoque por completo? Como si te pusieras encendido class Meta: exclude = ["fieldname"]. El problema aquí es que el Meta-enfoque es "estático", pero necesito algo dinámico. Ver stackoverflow.com/questions/20243735/…
Themerius

You cab di def __init __ (self, hide_condition = True, * args, ** kwargs) que es la forma más limpia ...
Visgean Skeloru

22

Para forma normal puedes hacer

class MyModelForm(forms.ModelForm):
    slug = forms.CharField(widget=forms.HiddenInput())

Si tiene un modelo de formulario, puede hacer lo siguiente

class MyModelForm(forms.ModelForm):
    class Meta:
        model = TagStatus
        fields = ('slug', 'ext')
        widgets = {'slug': forms.HiddenInput()}

También puedes anular el __init__método

class Myform(forms.Form):
    def __init__(self, *args, **kwargs):
        super(Myform, self).__init__(*args, **kwargs)
        self.fields['slug'].widget = forms.HiddenInput()

1

Si desea que el campo esté siempre oculto, use lo siguiente:

class MyForm(forms.Form):
    hidden_input = forms.CharField(widget=forms.HiddenInput(), initial="value")

0

Puedes usar css:

#id_fieldname, label[for="id_fieldname"] {
  position: absolute;
  display: none
}

Esto hará que el campo y su etiqueta sean invisibles.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.