web-dev-qa-db-fra.com

Remplacez un champ de formulaire Django par un champ masqué

J'ai un formulaire Django avec un RegexField, qui est très similaire à un champ de saisie de texte normal.

À mon avis, sous certaines conditions, je veux le cacher à l'utilisateur et essayer de garder le formulaire aussi similaire que possible. Quel est le meilleur moyen de transformer ce champ en un champ HiddenInput?

Je sais que je peux définir des attributs sur le terrain avec:

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

Et je peux définir la valeur initiale souhaitée avec:

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

Cependant, cela ne changera pas la forme du widget.

Quel est le meilleur/le plus "Django-y"/moins "hacky" moyen de faire de ce champ un champ <input type="hidden">?

115
Rory

Si vous avez un modèle et une vue personnalisés, vous pouvez exclure le champ et utiliser {{ modelform.instance.field }} pour obtenir la valeur.

vous pouvez également préférer utiliser dans la vue:

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

mais je ne suis pas sûr que cela protégera la méthode save sur post.

J'espère que ça aide.

153
christophe31

Cela peut aussi être utile: {{ form.field.as_hidden }}

178
semente

Tout d'abord, si vous ne souhaitez pas que l'utilisateur modifie les données, il semble alors plus simple d'exclure simplement le champ. Le fait de l'inclure en tant que champ masqué ajoute simplement plus de données à envoyer sur le réseau et invite un utilisateur malveillant à le modifier lorsque vous ne le souhaitez pas. Si vous avez une bonne raison d'inclure le champ mais de le cacher, vous pouvez passer un mot clé arg au constructeur du modèle. Quelque chose comme ça peut-être:

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.

Alors à votre avis:

form = MyModelForm(hide_condition=True)

Je préfère cette approche pour modifier les éléments internes du modelform dans la vue, mais c'est une question de goût.

44
rych

une option qui a fonctionné pour moi, définissez le champ dans le formulaire original comme suit:

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

alors, lorsque vous le remplacez dans la nouvelle classe, il conserve sa place.

43
Shay Rybak

Pour la forme normale, vous pouvez faire

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

Si vous avez un formulaire type, vous pouvez faire ce qui suit

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

Vous pouvez également remplacer la méthode __init__

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