afi
afi

Reputation: 603

How to pass form data as instance in Django?

info: I am trying to make an app like monthly instalment payment of items(property or etc).

I want when I fill out the customer form and select the product, I have to submit the payment form along with it and that payment will be linked to that customer. So in order to do this work, I have created a CustomerPayment model. I don't know how the models should be designed to do this.

Problem I am trying to submit the customer payment along with the customer form but my form is not submitted it's redirect me to back on form. i don't know how can i pass the both form data as instances of CustomerPayment (customer=customer & payment=payment).

Example:

enter image description here

models.py

class Customer(models.Model):
    name = models.CharField(max_length=255)
    phone = models.CharField(max_length=11, blank=True)

class Payment(models.Model):
    collect_by = models.ForeignKey(User, on_delete=models.SET_NULL)
    customer = models.ForeignKey(Customer, on_delete=models.SET_NULL)
    datetime = models.DateTimeField(auto_now_add=True)
    amount = models.DecimalField(default=0)
    remaining = models.DecimalField(default=0)

views.py

def order_form(request):

    customer_form = CustomerForm(request.POST)
    payment_form = PaymentForm(request.POST)

    if request.method == 'POST':

        if customer_form.is_valid() and payment_form.is_valid():
            customer = customer_form.instance.sales_men = request.user
            customer.save(commit=False)

            payment = payment_form.instance.collect_by = request.user
            payment.instance.customer = customer
            payment.save(commit=False)

            return redirect('/')

    context = {
        'customer_form': customer_form,
        'payment_form': payment_form,
    }
    return render(request, "payment/payment_create.html", context)

Upvotes: 2

Views: 1088

Answers (1)

markwalker_
markwalker_

Reputation: 12849

I think what you want to do in your view is something like this;

def order_form(request):

    customer_form = CustomerForm()
    payment_form = PaymentForm()

    if request.method == 'POST':
        customer_form = CustomerForm(request.POST)
        payment_form = PaymentForm(request.POST)

        if customer_form.is_valid() and payment_form.is_valid():
            customer = customer.save(commit=False)
            customer.sales_men = request.user
            customer.save()

            payment = payment_form.save(commit=False)
            payment.collect_by = request.user
            payment.customer = customer
            payment.save()

            return redirect('/')

    context = {
        'customer_form': customer_form,
        'payment_form': payment_form,
    }
    return render(request, "payment/payment_create.html", context)

If all the Customer model has is a name and phone number, you should consider moving that data on to the Payment. If nothing else, it'd simplify what you're doing in this view.

You've also got a FK on the Customer and a FK on the Payment both pointing to the same User. It feels like this would be simpler if a Payment had a FK to a User.

The User model already holds a name, so you might be able to drop the Customer model, of it there's data still needed make a Profile model which has a user = models.OneToOneField(). Then request.user.profile would give you a user profile for extra data

Upvotes: 1

Related Questions