Django Model Reference to Multiple Foreign Key with Child Property

Viewed 98

I have the following Models of customer details with each customers having different payment modes (eg. cash, online transfer, etc...) :

class Customer(models.Model):
    #some customer details

class Payment(models.Model):
    customer = models.ForeignKey(Customer, on_delete=models.RESTRICT, related_name='payments')
    payment_mode = models.CharField(max_length=255, blank=True, null=True) 

And I would like to add a new Invoice Model to include the customer as well as the customer's payment modes.

class Invoice (models.Model):
    customer = models.ForeignKey(Customer, on_delete=models.RESTRICT, related_name='payments')
    payment_mode = models.ForeignKey(Customer.payments.payment_mode, on_delete=models.RESTRICT)

I am going to create an Invoice for a customer and will input the customer's available payment mode. But the the invoice's payment mode is giving me an AttributeError: 'ReverseManyToOneDescriptor' object has no attribute 'payment_mode'.

May I know how do I set up the reference to the customer's child data? Thank you.

2 Answers

What you have is not a valid field definition.

You can reference Payment directly

payment_mode = models.ForeignKey(Payment, on_delete=models.RESTRICT)

Why is the Invoice model even required? You have the same fields already in the existing models. You can simply make a view to do this. For example,


def show_invoice(request, pk):
    # this pk value should be sent by your frontend and represents your Primary Key value for the current customer
    customer = Customer.objects.get(pk=pk)
    return render(request, 'some_html_page.html', {'customer': customer})

Now in your some_html_page.html, you can show the details you want using the 'context' to the render function ({'customer': customer}) we just passed.

Models in Django should be thought of as Tables in SQL; you are not supposed to make a new one every time you want to "infer" something, rather you should make them when you want to 'store' something (or normalize existing tables/models). The Invoice model does not do either of these two things.

You can give this a read to understand how to write views in Django this.

In the case where you really want to make an Invoice model you don't need to make a payment_mode field, since you're already pointing to the Customer model which is, in turn, pointing to the Payment model.

Related