如何在Django通用视图中为列表行生成PDF下载链接?
How to Add a PDF Download Link for Each Row in a Django ListView Table
To generate a PDF for each row in your ListView table, we'll use the ReportLab library (a go-to for PDF generation in Django) and build a dedicated view to handle PDF creation for individual booking records. Here's a step-by-step implementation tailored to your code:
1. Install Required Dependency
First, install ReportLab via pip:
pip install reportlab
2. Add a PDF Generation View to views.py
Create a new class-based view that fetches the specific container_booking record, populates a PDF with its details, and returns it as a downloadable file:
from django.http import HttpResponse from reportlab.pdfgen import canvas from .models import container_booking from django.contrib.auth.decorators import login_required from django.utils.decorators import method_decorator from django.views.generic import View @method_decorator(login_required, name='dispatch') class BookingPDFView(View): def get(self, request, pk, *args, **kwargs): # Fetch the target booking record booking = container_booking.objects.get(pk=pk) # Set up response headers for PDF download response = HttpResponse(content_type='application/pdf') response['Content-Disposition'] = f'attachment; filename="booking_confirmation_{pk}.pdf"' # Initialize PDF canvas p = canvas.Canvas(response) # Add booking details to the PDF (customize this layout as needed) p.setFont("Helvetica-Bold", 16) p.drawString(100, 750, "Container Booking Confirmation") p.setFont("Helvetica", 12) p.drawString(100, 720, f"Booking Date: {booking.date}") p.drawString(100, 700, f"Source: {booking.place_of_reciept}") p.drawString(100, 680, f"Destination: {booking.final_place_of_destination}") p.drawString(100, 660, f"Container: {booking.equipment_type} x {booking.quantity}") p.drawString(100, 640, f"Commodity: {booking.commodity}") p.drawString(100, 620, f"Agreed Rate: {booking.agreed_rate}") p.drawString(100, 600, f"Approval Status: {booking.approved}") # Finalize and save the PDF p.showPage() p.save() return response
3. Update urls.py to Include the PDF Route
Add a new URL pattern that maps to your PDF view:
url(r'^cont_bk/(?P<pk>[0-9]+)/pdf/$', views.BookingPDFView.as_view(), name='cont_bk-pdf'),
4. Modify the Template to Add Download Links
Update your table to include a "Download PDF" column and link each row to the new view:
<table class="table-striped table-hover table-bordered" width="100%"> <tr> <th>Date</th> <th>Source</th> <th>Destination</th> <th>Container</th> <th>Commodity</th> <th>Agreed Rate</th> <th>Edit</th> <th>Delete</th> <th>Status</th> <th>Download PDF</th> <!-- New column header --> </tr> {% for item in all_container %} <tr> <td>{{ item.date }} </td> <td>{{ item.place_of_reciept }} </td> <td>{{ item.final_place_of_destination }} </td> <td>{{ item.equipment_type }}{{ item.quantity }} </td> <td>{{ item.commodity }} </td> <td>{{ item.agreed_rate }} </td> <td><a href="{% url 'home:cont_bk-update' item.id %}"><i class="fas fa-edit"></i></a></td> <td><a href="{% url 'home:cont_bk-delete' item.id %}"><i class="fas fa-trash"></i></a></td> <td>{{ item.approved }}</td> <!-- New download link --> <td><a href="{% url 'home:cont_bk-pdf' item.id %}"><i class="fas fa-download"></i> Download</a></td> </tr> {% endfor %} </table>
Quick Notes:
- Customize PDF Layout: The example uses basic text, but you can expand it with tables, logos, or custom styling using ReportLab's full feature set.
- Alternative Libraries: If you prefer using HTML templates for easier styling, try WeasyPrint—it lets you render Django templates directly to PDF.
- Error Handling: Add a
try/exceptblock inBookingPDFViewto catch cases where thepkdoesn't exist (e.g., return a 404 page for invalid records).
内容的提问来源于stack exchange,提问作者Sachin Singh
相关产品推荐
相关产品推荐

