0

I'm writing an app that has an HTML page which must be capable of saving data into 2 models. I've created two separate forms and referenced them in the view, however the information is not saving into the DB.

Here are the views.py

def nuevoingreso(request):
    if request.method == "POST":
        formingreso = NuevoIngreso(request.POST)
        formprodingreso = NuevoProdIngreso(request.POST)
        if formingreso.is_valid():
            ingreso = formingreso.save(commit=False)
            ingreso.idUser = request.user
            ingreso.Condominio = get_object_or_404(Condominios, idCondominio=request.session["idCondominio"])
            ingreso.save()
            ingresoprod = formprodingreso.save()
            for i in range(5):
                if ProductosIngresos.SubtotalP != "" and ProductosIngresos.IvaP != "" and ProductosIngresos.TotalP != "":
                    ingresoprod.ProductosIngresos(Concepto=request.POST.get("Concepto"+str(i), ""), SubtotalP=request.POST.get("SubtotalP"+str(i), ""), IvaP=request.POST.get("IvaP"+str(i), ""), TotalP=request.POST.get("TotalP"+str(i), ""))
            ingresoprod.save()
            return HttpResponseRedirect("/propiedades/")
        else:
            return render(request, "immovelc/nuevoingreso.html",
                          {"formingreso": formingreso, "formprodingreso": formprodingreso})
    propiedadesing = PropiedadesCond.objects.all()
    context = ({"propiedadesing": propiedadesing})
    return render(request, "immovelc/nuevoingreso.html", context)

forms.py

class NuevoIngreso(ModelForm):
    class Meta:
        model = Ingresos
        fields = ["Numero", "Persona", "Fecha", "Observaciones", "Cobrado", "Subtotal", "Iva", "Total"]
        def clean(self):
            Numero = self.cleaned_data["Numero"]
            Persona = self.cleaned_data["Persona"]
            Fecha = self.cleaned_data["Fecha"]
            if not Numero:
                raise forms.ValidationError("El campo de numero es obligatorio")
            if not Persona:
                raise forms.ValidationError("El campo de cliente es obligatorio")
            if not Fecha:
                raise forms.ValidationError("El campo de fecha es obligatorio")

class NuevoProdIngreso(ModelForm):
    class Meta:
        model = ProductosIngresos
        fields = ["Concepto", "SubtotalP", "IvaP", "TotalP"]

models.py

class Ingresos(models.Model):
    idIngreso = models.AutoField(primary_key=True, null=False, max_length=15)
    idCondominio = models.ForeignKey(Condominios)
    idUser = models.ForeignKey(User)
    Numero = models.CharField(max_length=100)
    Persona = models.CharField(max_length=250, default="Ninguno")
    Cobrado = models.CharField(max_length=100, default=0)
    Observaciones = models.TextField(default="Ninguna")
    Fecha = models.DateField()
    Subtotal = models.CharField(max_length=100)
    Iva = models.CharField(max_length=100)
    Total = models.CharField(max_length=100)
    def __unicode__(self):
        return unicode(self.idIngreso)

class ProductosIngresos(models.Model):
    idProductoIngreso = models.AutoField(primary_key=True, null=False, max_length=15)
    idIngreso = models.ForeignKey(Ingresos)
    Concepto = models.CharField(max_length=500)
    SubtotalP = models.CharField(max_length=100)
    IvaP = models.CharField(max_length=100)
    TotalP = models.CharField(max_length=100)
    def __unicode__(self):
        return unicode(self.idProductoIngreso)

Thanks!

2
  • At least, your clean() method should be defined on a ModelForm, not inside Meta. Commented Jul 3, 2014 at 22:21
  • There might errors in submitted form, raised by form.is_valid(). Commented Jul 4, 2014 at 4:23

1 Answer 1

1

No offence, but this code is far from being correct.

Besides you've got many errors that you might want to remove.

Errors:

  • formprodingreso.is_valid() is never called
  • inside for i in range(5) you use a class as if it was an instance (ProductosIngresos.SubtotalP)
  • clean method in form has to be outside the Meta block

I believe what you want inside the loop is:

producto_ingreso = ProductosIngresos()
producto_ingreso.idIngreso = ingreso # better change to producto_ingreso.ingreso
producto_ingreso.Concepto=request.POST.get("Concepto"+str(i), "") # producto_ingreso.concepto
producto_ingreso.SubtotalP=request.POST.get("SubtotalP"+str(i), "") # producto_ingreso.subtotal_p
producto_ingreso.IvaP=request.POST.get("IvaP"+str(i), "")
producto_ingreso.TotalP=request.POST.get("TotalP"+str(i), ""))
producto_ingreso.save()

To make it cleaner, you can make this king of logic overridding the save() method of ModelForm. Or use inline formsets.

Confusion:

  • Model FKs are objects in Django, not integers. Better name them like condominio instead of idCondominio
  • Decimal columns (subtotal, iva, total) should be declared as deciaml i.e. models.DecimalField(max_digits=10, decimal_places=2)
  • clean method is intended for cross field validation (more than one field). Only one field should be validated by clean_numero f.e.

Over complication:

  • models have ID/PK by default, no need to explicit them (referenced as self.id or self.pk)
    • model unicode function is not giving any info
    • clean and ValidationError are superflous: modelform checks if attributes are requiered automatically

Convention errors:

  • attributes are always written_in_lowercase (SubtotalP -> subtotal_p)

I would seriously try to fix all of those if you dont want the developers maintaining your code hate you and make some voodoo on you.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.