with tutorial the español applications python django forms

python - tutorial - the django project



Hacer una clase de formulario Django con un número dinámico de campos (4)

Estoy trabajando en algo así como una tienda en línea. Estoy haciendo un formulario en el que el cliente compra un artículo, y ella puede elegir cuántos de estos artículos le gustaría comprar. Pero, en cada artículo que compra, debe elegir cuál sería su color. De modo que hay un número no constante de campos: si el cliente compra 3 artículos, debe obtener 3 cuadros <select> para elegir un color, si compra 7 artículos, debe obtener 7 de esos <select> recuadros.

Haré que los campos de formulario HTML aparezcan y desaparezcan usando JavaScript. ¿Pero cómo trato esto en mi clase de formulario de Django? Veo que los campos de formulario son atributos de clase, por lo que no sé cómo manejar el hecho de que alguna instancia de formulario debe tener 3 campos de color y 7.

¿Cualquier pista?


Aquí hay otra opción: ¿qué tal un formset ? Como tus campos son todos iguales, para eso se usan los conjuntos de formularios.

El administrador de django usa FormSet s + un poco de javascript para agregar líneas de longitud arbitrarias.

class ColorForm(forms.Form): color = forms.ChoiceField(choices=((''blue'', ''Blue''), (''red'', ''Red''))) ColorFormSet = formset_factory(ColorForm, extra=0) # we''ll dynamically create the elements, no need for any forms def myview(request): if request.method == "POST": formset = ColorFormSet(request.POST) for form in formset.forms: print "You''ve picked {0}".format(form.cleaned_data[''color'']) else: formset = ColorFormSet() return render(request, ''template'', {''formset'': formset}))

JavaScript

<script> $(function() { // this is on click event just to demo. // You would probably run this at page load or quantity change. $("#generate_forms").click(function() { // update total form count quantity = $("[name=quantity]").val(); $("[name=form-TOTAL_FORMS]").val(quantity); // copy the template and replace prefixes with the correct index for (i=0;i<quantity;i++) { // Note: Must use global replace here html = $("#form_template").clone().html().replace(/__prefix_/g'', i); $("#forms").append(html); }; }) }) </script>

Modelo

<form method="post"> {{ formset.management_form }} <div style="display:none;" id="form_template"> {{ formset.empty_form.as_p }} </div><!-- stores empty form for javascript --> <div id="forms"></div><!-- where the generated forms go --> </form> <input type="text" name="quantity" value="6" /> <input type="submit" id="generate_forms" value="Generate Forms" />



La forma en que lo haría es la siguiente:

  1. Cree una clase "vacía" que herede de froms.Form , así:

    class ItemsForm(forms.Form): pass

  2. Construya un diccionario de objetos de formularios que sean las formas reales, cuya composición dependería del contexto (por ejemplo, puede importarlos desde un módulo externo). Por ejemplo:

    new_fields = { ''milk'' : forms.IntegerField(), ''butter'': forms.IntegerField(), ''honey'' : forms.IntegerField(), ''eggs'' : forms.IntegerField()}

  3. En las vistas, puede usar la función de "tipo" nativa de Python para generar dinámicamente una clase de formulario con una cantidad variable de campos.

    DynamicItemsForm = type(''DynamicItemsForm'', (ItemsForm,), new_fields)

  4. Pase el contenido al formulario y preséntelo en la plantilla:

    Form = DynamicItemsForm(content) context[''my_form''] = Form return render(request, "demo/dynamic.html", context)

El "contenido" es un diccionario de valores de campo (por ejemplo, incluso request.POST). Puedes ver todo mi ejemplo explicado here .


puedes hacerlo como

def __init__(self, n, *args, **kwargs): super(your_form, self).__init__(*args, **kwargs) for i in range(0,n): self.fields["field_name %d" % i] = forms.CharField()

y cuando creas una instancia de formulario, simplemente haces

forms = your_form(n)

es solo la idea básica, puedes cambiar el código a lo que quieras. :RE