with widgets valid modelforms manually formmodel form creating create django forms fieldset

valid - modelform widgets django



Django y fieldsets en ModelForm (5)

Creo que este fragmento hace exactamente lo que quieres. Le da una subclase de formulario que le permite subdividir declarativamente su formulario en conjuntos de campo e iterar a través de ellos en su plantilla.

Actualización: ese fragmento se ha convertido desde entonces en parte de django-form-utils

Sé que puede especificar conjuntos de campo en django para los ayudantes de administración. Sin embargo, no puedo encontrar nada útil para ModelForms. Solo algunos parches que no puedo usar. ¿Me estoy perdiendo de algo? ¿Hay alguna manera de lograr algo así como conjuntos de campos sin escribir manualmente cada campo en mi plantilla en la etiqueta correspondiente?

Idealmente quisiera iterar a través de un conjunto de BoundFields. Sin embargo, al hacer algo como esto al final de mi 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

falla ya que los elementos contenidos en mi estructura de datos son los campos crudos, no los BoundFields. Parece que BoundFields se genera sobre la marcha ... esto me entristece. ¿Podría crear mi propia subclase de formularios.Forma que contiene un concepto de conjuntos de campo (incluso uno áspero que no es compatible con versiones anteriores ... esto es solo para mi propio proyecto) y si es así, ¿puede dar cualquier puntero? No quiero meterme con el código django.



Este fue el código que desarrollé para comprender las etiquetas personalizadas (con enlaces). Lo apliqué para crear un fieldset.

Descargo de responsabilidad: Animo el uso de cualquiera de las respuestas anteriores, esto solo por el simple hecho de aprender.

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>


Los conjuntos de campos en formas de modelos todavía están en etapa de "diseño". Hay un ticket en el tracto Django con poca actividad.

Es algo en lo que he estado interesado en investigarme en un futuro cercano, pero como aún no lo he hecho, lo mejor que puedo ofrecer son estos fragmentos:

Editar: Acabo de notar esta pregunta nuevamente y me doy cuenta de que necesita una edición para señalar el proyecto de Carl, django-form-utils que contiene una clase de BetterForm que puede contener conjuntos de campo. Si te gusta este proyecto, dale un +1 por su respuesta a continuación :)


Una cosa que puede hacer es dividir sus conjuntos de campos lógicos en clases de formulario de modelo separadas.

class PersonalInfoForm (forms.ModelForm): class Meta: model=MyModel fields=(''field1'', ''field2'', ...) class TermsForm (forms.ModelForm): class Meta: model=MyModel fields=(''fieldX'', ''fieldY'', ...)

Páselos a su plantilla en diferentes variables y divida los conjuntos de formularios:

<form ...> <fieldset><legend>Personal Information</legend> {{ personal_info_form }} </fieldset> <fieldset><legend>Terms and Conditions</legend> {{ terms_form }} </fieldset> </form>

En ese sentido, cada una de sus clases de formulario es solo un fragmento del formulario HTML real.

Introduce un toque de complejidad cuando llamas guardar en el formulario. Probablemente quiera pasar commit = False y luego fusionar los objetos resultantes. O simplemente evite usar ModelForm.save por completo y llene su objeto modelo a mano con ''cleaned_data''