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?

Rory
fuente

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.

christophe31
fuente
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 }}

semente
fuente
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.

Shay Rybak
fuente
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.

rych
fuente
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()
anjaneyulubatta505
fuente
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")
Zags
fuente
0

Puedes usar css:

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

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

usuario20310
fuente