web-dev-qa-db-fra.com

Django ModelForm pour avoir une entrée cachée

J'ai donc mon modèle TagStatus. J'essaye de faire un ModelForm pour cela. Cependant, mon formulaire nécessite que l'entrée masquée soit renseignée avec le {{tag.name}}. J'ai parcouru la documentation et je ne sais pas comment faire du champ de balise une entrée masquée. Peut-être qu'un ModelForm n'est pas la solution?

models.py:

class TagStatus(models.Model):
    user = models.ForeignKey(User, null=True, unique=True)
    status = models.CharField(max_length=2, choices=tag_statuses)
    tag = models.ForeignKey(Tag, null=True, blank=True)

    def __unicode__(self):
        return self.status

    def save(self, *args, **kwargs):
        super(TagStatus, self).save(*args, **kwargs)

class TagStatusForm(modelForm):
    class Meta:
        model = TagStatus
        fields = ('status','tag') 
        widgets = {
             'select': Select,
             'tag': ???
        }

Django views.py:

@login_required
def tags(request):
    all_tags = Tag.objects.all()
    context = base_context(request)
    if request.method == 'POST':
        if 'status_check' in request.POST:
            status_form = TagStatusForm(request.POST)
            #if request.is_ajax():
            if status_form.is_valid():
                status_form.save()
                response = simplejson.dumps({"status": "Successfully changed status"})
            else:
                response = simplejson.dumps({"status": "Error"})
                return HttpResponse (response, mimetype='application/json')
    status_form = TagStatusForm()
    context['status_form'] = status_form
    context['all_tags'] = all_tags
    return render_to_response('tags/tags.html', context, context_instance=RequestContext(request))

modèle:

{% for tag in all_tags %}
....
<form class="Nice" id="status-form" method="POST" action="">
     {% csrf_token %}
      <input type="hidden" name="status_check" />
      <input type='hidden' name="tag" value="{{ tag.name }}" />
     {{ status_form.status }}
</form>
...
{% endfor %}

Comment pourrais-je créer une entrée masquée via Django ModelForm, puis la renseigner via le modèle?

59
Modelesq

Pour transformer un champ de ModelField en champ masqué, utilisez un widget HiddenInput. ModelForm utilise un widget par défaut sensible pour tous les champs, il vous suffit de le remplacer lors de la construction de l'objet.

class TagStatusForm(forms.ModelForm):
    class Meta:
        model = TagStatus
        widgets = {'tag': forms.HiddenInput()}
102
Josh

Il y a 3 façons possibles (autant que je sache) de rendre les champs cachés dans Django -

1. Vous pouvez déclarer un champ normalement dans forms.py mais dans vos fichiers HTML de modèles, utilisez {{ form.field.as_hidden }}

2. in forms.py utilise directement un widget de saisie masqué.

class MyForm(forms.Form):
    hidden_field = forms.CharField(widget=forms.HiddenInput())

Une fois le champ masqué, vous pouvez renseigner la valeur du champ dans les modèles. Votre champ caché est maintenant prêt pour le rendu. 

3. Forme équivalente (merci à @Modelesq pour le partage de ce nugget). Ici, aucun Django n'est impliqué. Les modifications sont effectuées au niveau du modèle HTML. <input type="hidden" name="tag" value="{{ tag.name }}" />

71

Je cherchais un moyen de cacher toutes les entrées: 

class TagStatusForm(forms.ModelForm):
    class Meta:
        model = TagStatus

    def __init__(self, *args, **kwargs):
        super(TagStatusForm, self).__init__(*args, **kwargs)
        for field in self.fields:
            self.fields[field].widget = forms.HiddenInput()
0
Lucas B

J'ai posté un moyen de le faire avec des vues génériques basées sur les classes ici :

from Django.forms import HiddenInput

from Django.forms.models import modelform_factory

_patient_create_form = modelform_factory(
    models.Patient,
    fields=['name', 'caregiver_name', 'sex', 'birth_date',
            'residence', 'country'],
    widgets={'country': HiddenInput()})

class PatientCreate(LoginRequiredMixin, UserOrgRequiredMixin, CreateView):
    form_class = _patient_create_form
    template_name = 'healthdbapp/patient_form.html'
0
dfrankow