Django外键使用:如何筛选展示指定租赁点的关联图书
Django外键关联数据按租赁点过滤展示实现方案
问题根因
当前实现出现全量图书在所有租赁点页展示的核心原因有两个:
RentalDetailView仅获取了单个租赁点对象,没有对关联图书做归属过滤- 模板遍历的
object_list是全量图书集合,没有利用Django外键的反向关联能力取当前租赁点下的图书
具体修改步骤
1. 修正视图层逻辑
首先补上你原有代码里RentalDetailView模板路径缺失的末尾单引号,再重写get_context_data方法注入过滤后的关联图书数据:
class BookListView(ListView): model = Book template_name='book.html' class BookDetailView(DetailView): model = Book template_name='book_detail.html' class RentalListView(ListView): model = Rental template_name='rental_list.html' class RentalDetailView(DetailView): model = Rental template_name='rental_detail.html' # 补全原有缺失的单引号 def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) current_rental = self.get_object() # 利用外键定义的related_name反向查询当前租赁点关联的所有图书 context['rental_books'] = current_rental.display.all() return context
提示:你当前ForeignKey设置的
related_name="display"语义不够直观,可将模型中该字段改为related_name="books",后续查询时写current_rental.books.all()可读性更强。
2. 修正租赁点详情页模板
原有模板遍历的object_list是ListView专用的全量对象集合,DetailView场景下需要遍历我们刚才注入的、过滤完成的rental_books变量,同时增加无图书时的提示逻辑:
<h1 style="font-size:11px; text-align:right;"><a href="{%url 'home' %}">Powrót do strony głównej</a></h1> <div class="rental-basic"> <h2>{{ object.rental_name }}</h2> <p>地址:{{ object.rental_adress }}</p> </div> {% block content %} <h3>可借阅图书列表</h3> {%for book in rental_books%} <div class="book-entry"> <h2><a href="{% url 'book_detail' book.pk %}">{{book.book_title}}({{ book.get_book_genre_display }})</a></h2> <p>作者:{{ book.book_author }}</p> </div> {% empty %} <p>该租赁点暂无上架图书</p> {% endfor %} {% endblock content %}
模板中用{% empty %}标签即可实现无关联图书时的提示效果,get_book_genre_display是Django为choice字段自动生成的方法,可直接输出选项对应的可读文本,无需展示存储的3位缩写编码。
注意事项
- 确认路由配置正确,租赁点详情页路由需要携带主键参数,参考格式:
path('rental/<int:pk>/', RentalDetailView.as_view(), name='rental_detail'),否则DetailView无法定位当前访问的租赁点对象 - 不要在租赁点详情页直接遍历
Book.objects.all(),该查询会返回所有图书,必然出现跨租赁点数据展示问题 - 外键关联查询时,Django会自动按
book_rental_id = 当前租赁点id的规则过滤数据,无需手动写SQL查询条件
内容的提问来源于stack exchange,提问作者r.b
相关产品推荐
相关产品推荐

