variable tutorial template tag examples español django django-forms

tutorial - django en línea con formas personalizadas



django{% block %} (3)

Probablemente la fábrica de formset y el formset en línea deberían resolver su problema ... Puede modificar o anular los campos de formulario creados a partir de modelos. Para los modelos secundarios, puede usar formularios en línea ...

Conjuntos de formularios y formularios en línea ...

Una posible solución:

en su definición de formulario:

class CarInfoFrm(forms.ModelForm): class Meta: model = CarInfo fields = (....) carInfoForm = inlineformset_factory(Complaint, CarInfo, form=carInfoFrm,) CustomerForm = inlineformset_factory(Complaint, Customer, form=carInfoFrm,)

En su opinión:

complaint = Complaint() carInfo = CarInfo() customer = Customer() cus_form = CustomerForm(parameters, instance=complaint) car_form = CarInfoForm(parameters, instance=complaint) comp_form = ComplaintForm(parameters, instance=complaint) if cus_form.is_valid() and ...... : comp = comp_form.save(commit=False)#do not save it yet comp.<attr> = "some_value" #you can edit your data before save... comp.save() car = car_form(commit=False) # do as complaint form... edit and save...

EDITAR: hago un misteke al definir el parámetro de instancia mientras guardo las formas en línea. Así que lo corrijo ...

Cuando actualice registros existentes, no tendrá problemas, pero es mejor usarlos como:

if comp_form.is_valid(): comp = comp_form.save(commit=False) comp.<attr> = "some_value" comp.save() if car_form.is_valid(): # edit if neccessary then save... if cust_form.is_Valid(): # edit if neccessary then save...

Lo que hace que sea más fácil es que, al definir su formulario, establezca un formulario principal a través de una clave externa

carInfoForm = inlineformset_factory(Complaint, CarInfo, form=carInfoFrm,)

Y cuando actualiza utilizando el formulario en línea, lo inicializa con su registro Compalaint principal,

car_form = CarInfoForm(parameters, instance=complaint)

Entonces, car_form no acepta una instancia de carInfo, sino una instancia de queja (ese fue mi error en mi primera respuesta, así que lo corrijo). si crea un nuevo registro, lo vincula automáticamente al registro de reclamo relacionado. Si se trata de una actualización, solo actualiza los campos que desee.

Para mí, es mejor usar los métodos del framework en lugar de escribir tus propios. Al hacer esto, garantizará que todos los controles de validación sean hechos por django.

Hola, tengo un modelo de dominio, utilizado en la aplicación Django, que me gustaría presentar en un solo formulario. Creé mi aplicación con ModelForms personalizados (sin muchos cambios, algunos campos excluidos, etc.). Las dependencias del modelo son las siguientes:

Complaint / .--- CarInfo .--- Customer

Mi función de vista se ve así:

def make(request): if request.method == ''POST'': parameters = copy.copy(request.POST) complaint = Complaint() carInfo = CarInfo() customer = Customer() customer_form = CustomerForm(parameters, instance=customer) carInfo_form = CarInfoForm(parameters, instance=carInfo) parameters[''complaint_date''] = get_current_date() parameters[''customer''] = 1 # dummy value to allow validation success parameters[''car_info''] = 1 # dummy value to allow validation success form = ComplaintForm(parameters, instance=complaint) if form.is_valid() and customer_form.is_valid() and carInfo_form.is_valid(): carInfo_form.save() customer_form.save() parameters[''customer''] = customer.id parameters[''car_info''] = carInfo.id form = ComplaintForm(parameters, instance=complaint) form.save() return index(request) else: form = ComplaintForm() carInfo_form = CarInfoForm() customer_form = CustomerForm() return render_to_response(''complaints/make_complaint.html'', {''complaint_form'' : form, ''customer_form'' : customer_form, ''carInfo'' : carInfo_form})

No me gusta mucho este enfoque, además no funciona en todos los entornos; no he encontrado la razón por la que no funciona. He estado buscando arreglar un poco este código y encontré algo así como formset en línea (http://docs.djangoproject.com/en/dev/topics/forms/modelforms/#inline-formsets). Esta solución parece estar bien, pero dado que mis formularios están personalizados, puedo usarlos.

Tal vez alguien podría ofrecerme algunos consejos sobre cómo resolver adecuadamente este caso. Las soluciones más limpias son muy apreciadas.

EDITADO Hay un caso para mí, donde estas soluciones simplemente no funcionan. A pesar de establecer valores ficticios en claves externas, cuando llamo is_valid () obtengo FALSE, con un mensaje de error que indica que estos campos no están configurados. Estoy observando este problema con django 1.2.5 - ocurre en el servidor que intento ejecutar esta aplicación, sin embargo, mi computadora portátil (también django 1.2.5) no tiene este problema.


Puede cambiar la fecha de reclamo de su modelo de Queja a algo como esto

complaint_date = models.DateField(default=datetime.date.today())

de esa forma puedes deshacerte de

parameters[''complaint_date''] = get_current_date()

En cuanto a su vista multiforme, puede usar formularios independientes para su comportamiento deseado.

Al excluir el fk del automóvil y del cliente en el formulario de reclamo, los formularios deben validar. Compruebe el .is_valid () de los 3 formularios al mismo tiempo y luego guarde los 2 formularios de los que depende su objeto de queja, cree el objeto de queja sin compromiso con la base de datos (commit = False), agregue los id del cliente y coche a ese objeto, luego guardar.

en tu opinión.

def make(request): if request.method == ''POST'': customer_form = CustomerForm(request.POST) carInfo_form = CarInfoForm(request.POST) form = ComplaintForm(request.POST) if form.is_valid() and customer_form.is_valid() and carInfo_form.is_valid(): car_instance = carInfo_form.save() customer_instance = customer_form.save() complaint_instance = form.save(commit=False) complaint_instance.car_info = car_instance complaint_instance.customer_info = customer_instance complaint_instance.save() return index(request) else: form = ComplaintForm() carInfo_form = CarInfoForm() customer_form = CustomerForm() context = { ''complaint_form'' : form, ''customer_form'' : customer_form, ''carInfo'' : carInfo_form, } return render_to_response(''complaints/make_complaint.html'', context, context_instance=RequestContext(request))

editar:

los modelos se ven así:

class CarInfo(models.Model): some_car_info = models.CharField() class Customer(models.Model): some_customer_info = models.CharField() class Complaint(models.Model): car_info = models.ForeignKey(CarInfo) customer_info = models.ForeignKey(Customer) some_complaint_info = models.CharField()

forms.py debe verse así:

class CarInfoForm(forms.ModelForm): class Meta: model = CarInfo class CustomerForm(forms.ModelForm): class Meta: model = Customer class ComplaintForm(forms.ModelForm): class Meta: model = Complaint exclude = (''car_info'', ''customer_info'',) # or include = (''some_complaint_info'',)

Vamos a caminar por la vista que escribí arriba: form in view docs

  • En el primer paso, no hay un método request.method, así que creamos 3 formularios independientes .

    else: form = ComplaintForm() carInfo_form = CarInfoForm() customer_form = CustomerForm()

  • estos formularios se pasan a la plantilla y se procesan.

  • Cuando se llama de nuevo a la vista con request.method == "POST" evaluando verdadero, creamos las 3 instancias de formulario enlazado usando los datos de nuestra solicitud.POST.

    if request.method == ''POST'': customer_form = CustomerForm(request.POST) carInfo_form = CarInfoForm(request.POST) form = ComplaintForm(request.POST)

  • Luego llamamos al método .is_valid () en cada formulario . En nuestro ejemplo, ya que excluimos los campos de clave externa ''customer_info'' y ''car_info'' en nuestro formulario modelo de reclamo, cada formulario solo verifica que el campo de entrada char lo valida.

  • Si todos los pasos de validación se aprueban, podemos comenzar a guardar nuestros formularios en modelos y en este caso debemos tener cuidado al completar los fk requeridos por nuestra queja:

    if form.is_valid() and customer_form.is_valid() and carInfo_form.is_valid(): car_instance = carInfo_form.save() customer_instance = customer_form.save()

  • Con esos 2 formularios podemos llamar a .save () como de costumbre. Sin embargo, asignaremos el valor de retorno a car_instance y customer_instance. Estos contendrán las instancias de los modelos CarInfo y Cliente que acabamos de crear utilizando el método .save () en el formulario.

  • A continuación, utilizando el argumento commit=False en el método .save (), podemos crear un objeto a partir del formulario enlazado (que contiene los datos request.POST) y no guardarlo en la base de datos.

    complaint_instance = form.save(commit=False) complaint_instance.car_info = car_instance complaint_instance.customer_info = customer_instance complaint_instance.save()

  • Para aclarar esto, también podría haber creado un nuevo objeto de Queja como este:

    complaint_info = form.cleaned_data.get(''some_complaint_info'') complaint_instance = Complaint(car_info=car_instance, customer_info=customer_instance, some_complaint_info=some_complaint_info) complaint_instance.save()

  • hacer


Creo que ya tienes el enfoque más simple y limpio, pero si quieres ir con formularios, prueba estos enlaces:

EDITAR. Supongo que puede experimentar problemas debido a los valores ficticios (y la solicitud de modificación. POST, puedo seguir adivinando :), pero @kriegar mostró cómo puede evitar esto. De todos modos, no hay nada difícil en guardar varios formularios en una vista; Las Formas de Django soportan este caso lo suficientemente bien. Mi punto es que hacer esto explícitamente es la forma más simple y limpia, los conjuntos de formularios no mejorarán mucho la situación.