44 votes

Obtenez le type de widget de formulaire Django à partir du modèle.

Je parcours les champs d'un formulaire et pour certains d'entre eux, je souhaite une mise en page légèrement différente, ce qui nécessite une modification du code HTML.

Pour faire cela avec précision, j'ai juste besoin de connaître le type de widget. Son nom de classe ou quelque chose de similaire. En python standard, c'est facile ! field.field.widget.__class__.__name__

Malheureusement, vous n'êtes pas autorisé à accéder aux variables soulignées dans les modèles. Super !

Vous peut test field.field.widget.input_type mais cela ne fonctionne que pour le texte/mot de passe <input ../> types. J'ai besoin de plus de résolution que ça.

Pour moi, aussi difficile que cela puisse paraître, il est plus logique de le faire au niveau des modèles. J'ai externalisé la partie du code qui gère le HTML pour les champs vers un modèle séparé qui est inclus dans la boucle de champ. Cela signifie qu'il est cohérent à travers ModelForm et standard Form (ce qui ne serait pas vrai si j'écrivais une classe Form intermédiaire).

Si vous voyez une approche universelle qui ne m'oblige pas à modifier une vingtaine de formulaires, faites-le moi savoir !

0 votes

Rapport de bogue pertinent ou demande de fonctionnalité : code.djangoproject.com/ticket/13009

0voto

Aron Ysidoro Points 922

Voici ma réponse pour générer un formulaire à l'aide du champ {%. %} pour parcourir les champs en boucle. Similaire à la réponse précédente mais avec un peu de formatage CSS :

{% for field in form %}

<div class="control-group">
  <label for="{{ field.id_for_label }}" id="{{ field.id_for_label }}" class="control-label">
    {% if field.field.required %}
        <span class="red">*</span>
    {% endif %}
    {{ field.label }}:</label>
  <div class="controls">
    {{ field }}
  </div>
</div>

{% endfor %}

0voto

Gregorio Points 137

Vous pouvez faire en sorte que chaque vue qui gère des formulaires hérite d'une vue générique personnalisée où vous chargez dans le contexte les métadonnées dont vous avez besoin dans les modèles. La vue générique des formulaires devrait inclure quelque chose comme ceci :

class CustomUpdateView(UpdateView):
    ...
    def get_context_data(self, **kwargs):
       context = super().get_context_data(**kwargs)
       ...
       for f, value in context["form"].fields.items():
          context["form"].fields[f].type = self.model._meta.get_field(f).get_internal_type()
       ...
       return context

Dans le modèle, vous pouvez accéder à ces propriétés personnalisées par le biais de field.field :

{% if field.field.type == 'BooleanField' %}
     <div class="custom-control custom-checkbox">
     ...
     </div>
{% endif %}

En utilisant le débogueur de PyCharm ou Visual Studio Code, vous pouvez voir toutes les métadonnées disponibles, si vous avez besoin d'autre chose que le type de champ.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X