Экспорт таблицы с внешним ключом в excel

У меня есть эти 2 модели:

class Canva(models.Model):

name = models.CharField(null=True, blank=True, max_length=255)
site = models.CharField(null=True, blank=True, max_length=255)

def get_absolute_url(self):
    return reverse('bilans:canva_detail', kwargs={'pk': self.pk})

def __str__(self):
    return self.name

class Bilan(models.Model):

agregat = models.CharField(null=True, blank=True, max_length=255)
SCF = models.CharField(null=True, blank=True, max_length=255)
canva = models.ForeignKey('Canva', null=True, blank=True, on_delete=models.CASCADE, related_name='bilan_canva')

У меня есть эта страница, на которой перечислены объекты Canva:

{% for c in canva %}
    <a class="btn btn-info btn-outline-dark w-auto mb-2" href='/canvas/consult/{{c.pk}}'>{{      c.name }}</a>
{% endfor %}

эта ссылка ведет на эту страницу, которая показывает объекты в Bilan, которые соответствуют первичному ключу canva:

{% for bilan in canva.bilan_canva.all    %}
    <table  width="100%" border="1">
      <tbody>
          <tr>
          <th scope="col">{{ bilan.agregat }}</th>
          <th scope="col"> {{ bilan.SCF }} </th>
          </tr>
      </tbody>
    </table>
{% endfor %}

Я добавил эту ссылку в конце html страницы для экспорта в excel:

href="{% url 'bilans:export_excel' %}" role="button" class="btn btn-secondary w-50">export to excel

это view.py:

def export_users_xls(request):    
    
    response = HttpResponse(content_type='application/ms-excel')
    response['Content-Disposition'] = 'attachment; filename="Canvas.xls"'

    wb = xlwt.Workbook(encoding='utf-8')
    ws = wb.add_sheet('canvas list') # this will make a sheet named Users Data

    # Sheet header, first row
    row_num = 0

    font_style = xlwt.XFStyle()
    font_style.font.bold = True

    columns = ['agregat', 'scf', 'mois1', ]

    for col_num in range(len(columns)):
        ws.write(row_num, col_num, columns[col_num], font_style) # at 0 row 0 column 

    # Sheet body, remaining rows
    font_style = xlwt.XFStyle()

    rows = Bilan.objects.filter(canva_id=1).values_list('agregat', 'SCF')
    for row in rows:
        row_num += 1
        for col_num in range(len(row)):
            ws.write(row_num, col_num, row[col_num], font_style)

    wb.save(response)

    return response

вместо rows = Bilan.objects.filter(canva_id=1), я хочу, чтобы ссылка автоматически брала canva.pk

мои урлы:

urlpatterns = [

    path('', views.HomeView.as_view(), name='home'),
    path('canvas/list2/',views.index2, name='list2_canvas'), 
    path('canvas/consult/<int:pk>/', views.CanvaConsultlView.as_view(), name='canva2_detail'),
    path('canvas/consult/export/', views.export_users_xls, name='export_excel'), 
     

]

urlpatterns = [
    path('', views.HomeView.as_view(), name='home'),
    path('canvas/list2/',views.index2, name='list2_canvas'), 
    path('canvas/consult/<int:pk>/', views.CanvaConsultlView.as_view(), name='canva2_detail'),
    path('canvas/consult/export/<int:pk>/', views.export_users_xls, name='export_excel'), 
]

и в вашем шаблоне:

href="{% url 'bilans:export_excel' canva.pk %}" role="button" class="btn btn-secondary w-50">export to excel

найдено рабочее решение:

модифицировал функцию, добавив pk:

def export_users_xls(request, pk):

response = HttpResponse(content_type='application/ms-excel')
response['Content-Disposition'] = 'attachment; filename="Canvas.xls"'

wb = xlwt.Workbook(encoding='utf-8')
ws = wb.add_sheet('canvas list') # this will make a sheet named Users Data

# Sheet header, first row
row_num = 0

font_style = xlwt.XFStyle()
font_style.font.bold = True

columns = ['agregat', 'scf', 'mois1', ]

for col_num in range(len(columns)):
    ws.write(row_num, col_num, columns[col_num], font_style) # at 0 row 0 column 

# Sheet body, remaining rows
font_style = xlwt.XFStyle()

rows = Bilan.objects.filter(**canva_id=pk**).values_list('agregat', 'SCF')
for row in rows:
    row_num += 1
    for col_num in range(len(row)):
        ws.write(row_num, col_num, row[col_num], font_style)

wb.save(response)

return response
Вернуться на верх