Django django-tables2中如何向render_foo回传slug参数
实现方案
核心问题排查
linkify=True报错原因:django-tables2默认调用关联模型的get_absolute_url()方法生成跳转链接,未定义该方法时直接使用会抛出异常。- 自定义render方法拿不到slug原因:
- 视图层queryset使用
.values()时未查询关联Author表的author_slug字段,数据本身就没带slug参数 render_book_count方法参数写法错误,django-tables2的自定义列渲染方法需要通过record参数获取整行数据,直接写author_slug作为形参无法接收到对应值。- 原代码存在基础语法错误:模型外键未指定
on_delete参数、SlugField字段名拼写错误、unique参数拼写错误、分组统计queryset分组维度错误。
- 视图层queryset使用
分步修复
1. 修正模型层代码
补全缺失字段、修正拼写错误,可选添加get_absolute_url支持linkify特性:
# models.py from django.db import models from django.urls import reverse class Library(models.Model): name = models.CharField(max_length=128) library_slug = models.SlugField(unique=True) class Author(models.Model): library = models.ForeignKey(Library, on_delete=models.CASCADE) name = models.CharField(max_length=128) # 补全姓名字段,用于列表展示 author_slug = models.SlugField(unique=True) # 修正原代码拼写、缺等号问题 # 可选:定义get_absolute_url后可直接使用linkify=True实现跳转 def get_absolute_url(self): return reverse('author_book_list', kwargs={'author_slug': self.author_slug}) class Book(models.Model): author = models.ForeignKey(Author, on_delete=models.CASCADE) title = models.CharField(max_length=128) # 补全书名、类型字段,对应作者详情页表格 genre = models.CharField(max_length=64) book_slug = models.SlugField(unique=True)
2. 配置路由
添加对应页面路由,确保slug参数可以被正确接收:
# urls.py from django.urls import path from . import views urlpatterns = [ path('library/', views.LibraryTableView, name='library_list'), path('author/<slug:author_slug>/', views.AuthorTableView, name='author_book_list'), ]
3. 修正视图层查询逻辑
查询时带出需要的author_slug字段,修正分组统计逻辑和过滤逻辑:
# views.py from django.shortcuts import render from django.db.models import Count from .models import Book from .tables import LibraryTable, AuthorTable def LibraryTableView(request): # 按作者维度分组统计书籍数量,关联查询带出作者名、author_slug queryset = Book.objects.values( 'author_id', 'author__name', 'author__author_slug' ).annotate(book_count=Count('id')) table = LibraryTable(queryset) return render(request, 'library_list.html', {'table': table}) def AuthorTableView(request, author_slug): # 过滤当前作者下的所有书籍 queryset = Book.objects.filter(author__author_slug=author_slug) table = AuthorTable(queryset) return render(request, 'author_book_list.html', {'table': table})
4. 修正表格自定义渲染逻辑
通过record参数获取行数据,反向解析路由拼接正确跳转链接:
# tables.py import django_tables2 as tables from django.utils.html import format_html from django.urls import reverse class LibraryTable(tables.Table): class Meta: fields = ('author__name', 'book_count') verbose_name = { 'author__name': 'Author', 'book_count': 'Book Count' } def render_book_count(self, value, record): # 从当前行数据中取出提前查询的author_slug author_slug = record['author__author_slug'] # 反向解析路由生成跳转地址,避免硬编码 jump_url = reverse('author_book_list', kwargs={'author_slug': author_slug}) return format_html('<a href="{}">{}</a>', jump_url, value) # 作者详情页书籍表格 class AuthorTable(tables.Table): class Meta: model = Book fields = ('title', 'genre') verbose_name = { 'title': 'Title', 'genre': 'Genre' }
效果说明
修复后图书馆列表页的书籍计数列会自动生成带作者slug的跳转链接,点击对应作者的计数数字,即可跳转到该作者的专属书籍列表页,展示该作者名下所有书籍的标题、类型信息。
如果需要实现点击作者名跳转,只需在LibraryTable中给作者列添加配置author__name = tables.Column(linkify=True)即可,不需要额外写render方法。
内容的提问来源于stack exchange,提问作者ducktapeonmydesk
相关产品推荐
相关产品推荐

