41 votes

Django et fieldsets sur ModelForm

Je sais que vous pouvez spécifier des ensembles de champs dans Django pour les aides d'administration. Cependant, je ne trouve rien d'utile pour les ModelForms. Juste quelques correctifs que je ne peux pas utiliser. Est-ce que quelque chose m'échappe ? Existe-t-il un moyen de réaliser quelque chose comme des fieldsets sans écrire manuellement chaque champ de mon modèle dans la balise appropriée.

Dans l'idéal, je voudrais itérer dans un ensemble de BoundFields. Cependant, en faisant quelque chose comme ceci à la fin de mon ModelForm :

    fieldsets = []
    fieldsets.append(('Personal Information',
                      [username,password,password2,first_name,last_name,email]),) # add a 2 element tuple of string and list of fields
    fieldsets.append(('Terms & Conditions',
                      [acceptterms,acceptprivacy]),) # add a 2 element tuple of string and list of fields

ne fonctionne pas car les éléments contenus dans ma structure de données sont les champs bruts, pas les BoundFields. Il semble que les BoundFields soient générés à la volée... cela me rend triste. Pourrais-je créer ma propre sous-classe de forms.Form qui contienne un concept de fieldsets (même approximatif et non rétrocompatible... c'est juste pour mon propre projet) et si oui, pouvez-vous me donner des indications ? Je ne veux pas toucher au code de Django.

0voto

Wtower Points 135

Voici le code que j'ai développé afin de comprendre les balises personnalisées (avec des liens). Je l'ai appliqué pour créer un fieldset.

Clause de non-responsabilité : J'encourage l'utilisation de toutes les réponses ci-dessus, c'était juste pour le plaisir d'apprendre.

templatetags/myextras.py :

from django import template
from django.template import Context

register = template.Library()

class FieldsetNode(template.Node):
    """ Fieldset renderer for 'fieldset' tag """
    def __init__(self, nodelist, fieldset_name):
        """ Initialize renderer class
        https://docs.djangoproject.com/en/1.8/howto/custom-template-tags/#writing-the-renderer
        :param nodelist: a list of the template nodes inside a block of 'fieldset'
        :param fieldset_name: the name of the fieldset
        :return: None
        """
        self.nodelist = nodelist
        self.fieldset_name = fieldset_name

    def render(self, context):
        """ Render the inside of a fieldset block based on template file
        https://docs.djangoproject.com/en/1.8/howto/custom-template-tags/#auto-escaping-considerations
        :param context: the previous template context
        :return: HTML string
        """
        t = context.template.engine.get_template('myapp/fieldset.html')
        return t.render(Context({
            'var': self.nodelist.render(context),
            'name': self.fieldset_name,
        }, autoescape=context.autoescape))

@register.tag
def fieldset(parser, token):
    """ Compilation function for fieldset block tag
    Render a form fieldset
    https://docs.djangoproject.com/en/1.8/howto/custom-template-tags/#writing-the-compilation-function
    https://docs.djangoproject.com/en/1.8/howto/custom-template-tags/#parsing-until-another-block-tag
    :param parser: template parser
    :param token: tag name and variables
    :return: HTML string
    """
    try:
        tag_name, fieldset_name = token.split_contents()
    except ValueError:
        raise template.TemplateSyntaxError("%r tag requires a single argument" % token.contents.split()[0])
    if not (fieldset_name[0] == fieldset_name[-1] and fieldset_name[0] in ('"', "'")):
        raise template.TemplateSyntaxError("%r tag's argument should be in quotes" % tag_name)
    nodelist = parser.parse(('endfieldset',))
    parser.delete_first_token()
    return FieldsetNode(nodelist, fieldset_name[1:-1])

templates/myapp/fieldset.html :

<div class="fieldset panel panel-default">
    <div class="panel-heading">{{ name }}</div>
    <div class="panel-body">{{ var }}</div>
</div>

templates/myapp/myform.html :

<form action="{% url 'myapp:myurl' %}" method="post">
    {% csrf_token %}
    {% fieldset 'General' %}
        {{form.myfield1 }}
    {% endfieldset %}
    {# my submit button #}
</form>

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