[Fixed]-How to data fetch by using has many through in django?

1👍

You don’t need product or year in your context. You can use relation between your models to get this information:

views.py

from django.shortcuts import render, get_object_or_404, redirect
from .models import Customer, Product, Year

# Create your views here.
def home(request):
    customer = Customer.objects.all
    context = {'customers': customer}
    return render(request, 'customer.html', context)

Now in your template you can get :

All product of a customer, with year by product

{% for customer in customers %}
   Customer : {{ customer }}<br>
   {% for product in customer.product_set.all %}
       Product : {{ product }} / Year :{{ product.year }}<br>
   {% endfor %}
{% endfor %}

But I don’t like put too much logic in template.
I advise you to create the data of your table in your view, even better in your model. And then generate your html table with this data.

Summary of the function you will need:
You can replace all() by a filter()

products = customer.product_set.all() # give you all product of a customer

UPDATE AFTER COMMENTS:

Views.py

from django.shortcuts import render, get_object_or_404, redirect
from .models import Customer, Product, Year

# Create your views here.
def home(request):
    customers = Customer.objects.all()
    years = Year.objects.all().values_list('year', flat=True).asc() # List of year name 
    rows = []
    for year in years:
        row = [year] + [None] * len(customers) # Row with year in first column, and the rest init with same size of customers list
        for idx, customer in enumerate(customers):
            quantities = customer.product_set.filter(year__year=year).valu e_list('quantity', flat=True) # filter product by year. That can return multiple product !!! 
            row[idx + 1] = ' ,'.join(quantities) # create a string of quantities
        rows.append(row) # Add new row in our rows list
    context = {'customers': customer,
               'rows': rows}
    return render(request, 'customer.html', context)

template:

{% extends 'base.html' %}
{% block customer %}
<div class="container">
  <h2>Players Table</h2>
  <p>Customer with Product</p>
  <table class="table">
    <thead>
      <tr>
          <th>Year/Product</th>
          {% for customer in customers %}
              <th>{{ customer.name }}</th>
          {% endfor %}
      </tr>
    </thead>
      <tbody>
        {% for row in rows %}
            <tr>
                {% for cell in row %}
                    <th>cell</th>
                {% endfor %}
            </tr>
        {% endfor %}
      </tbody>
  </table>
</div>

I think that can help you to understand how to resolve your problem. I don’t test this code, so maybe there is error. This is not perfect !

Leave a comment