Modificare un campo modulo Django in un campo nascosto


128

Ho una forma Django con a RegexField , che è molto simile a un normale campo di immissione testo.

A mio avviso, in determinate condizioni, voglio nasconderlo all'utente e cercare di mantenere il modulo il più simile possibile. Qual è il modo migliore per trasformare questo campo in un HiddenInputcampo?

So di poter impostare gli attributi sul campo con:

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

E posso impostare il valore iniziale desiderato con:

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

Tuttavia, ciò non cambierà la forma del widget.

Qual è il modo migliore / più "django-y" / minimo "hacky" per rendere questo campo un <input type="hidden">campo?

Risposte:


169

Se hai un modello personalizzato e visualizza puoi escludere il campo e utilizzare {{ modelform.instance.field }} per ottenere il valore.

inoltre potresti preferire utilizzare nella vista:

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

ma non sono sicuro che proteggerà il metodo di salvataggio per posta.

Spero che sia d'aiuto.


1
&quot;&quot; is not a valid value for a primary key.Finisco con un metodo is_valid dopo aver usato questa soluzione.
Jens Timmerman,

Sembra strano. Penso che sia correlato a qualcos'altro, stai visualizzando come HiddenInput la chiave primaria degli oggetti che stai creando? Se sì, non dovresti.
christophe31,

Forse questo è ovvio, ma dovrai importare i moduli prima che funzionino. from django import forms
teewuane,

2
su 1.7 usa questa sintassi: hidden_field_name = forms.CharField(label='reset', max_length=256, widget=forms.HiddenInput())dove la chiave è la sintassi del widget più recente alla fine. Modifica per le tue esigenze.
Marc

196

Questo può anche essere utile: {{ form.field.as_hidden }}


3
Questa è la risposta migliore IMHO. Ho sempre odiato usare il mio codice Python "controller" per determinare la visualizzazione di un campo modulo.
trpt4him,

Realizzo spesso un modello di modulo generico con forme croccanti. Se si utilizzano forme croccanti o si visualizzano i campi in un forloop semplice perché si desidera la struttura del modulo nella classe del modulo, il widget che sostituisce il modulo è il modo migliore per farlo. Bu se gestisci il rendering del tuo modulo nel tuo modello, infatti, questa soluzione è molto più chiara / pulita.
christophe31,

Vale la pena notare che questo sembra cancellare in anticipo tutte le classi che hai applicato al campo ...
John Aaron,

59

un'opzione che ha funzionato per me, definire il campo nella forma originale come:

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

quindi quando lo sostituisci nella nuova Classe, manterrà il suo posto.


45

In primo luogo, se non si desidera che l'utente modifichi i dati, sembra più semplice escludere semplicemente il campo. Includerlo come campo nascosto aggiunge semplicemente più dati da inviare via cavo e invita un utente malintenzionato a modificarlo quando non lo si desidera. Se hai una buona ragione per includere il campo ma nasconderlo, puoi passare una parola chiave arg al costruttore della modellistica. Qualcosa del genere forse:

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.

Quindi a tuo avviso:

form = MyModelForm(hide_condition=True)

Preferisco questo approccio alla modifica degli interni della modelform nella vista, ma è una questione di gusti.


11
solo un semplice suggerimento, kwargs.pop ('hide_condition', False) invece di kwargs ['hide_condition']. gestirai il caso no arg, avrai un default e del allo stesso tempo.
christophe31,

2
grazie per la punta, christophe31. Ho aggiornato con il tuo suggerimento, in quanto rende il codice molto più chiaro.
rych

1
È possibile nascondere completamente il campo con questo approccio? Come se ti accingessi class Meta: exclude = ["fieldname"]. Il problema qui è che l'approccio Meta è "statico", ma ho bisogno di qualcosa di dinamico. Vedere stackoverflow.com/questions/20243735/...
Themerius

You cab di def __init __ (self, hide_condition = True, * args, ** kwargs) che è il modo più pulito ...
Visgean Skeloru

22

Per la forma normale puoi farlo

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

Se hai un modello, puoi fare quanto segue

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

Puoi anche sostituire il __init__metodo

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

1

Se si desidera che il campo sia sempre nascosto, utilizzare quanto segue:

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

0

Puoi semplicemente usare CSS:

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

Ciò renderà il campo e la sua etichetta invisibili.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.