如何使用Django通用类视图按分类/客户筛选产品及交易数据
Django通用类视图按客户筛选交易记录实现方案
现有代码问题
- 筛选逻辑位置错误:在
get_context_data中过滤查询集不符合通用视图的设计规范,通用视图推荐重写get_queryset方法实现数据筛选,性能更优也更易维护 - 代码不完整:你写的
get_context_data方法没有返回context对象,运行会直接报错 - 取值逻辑错误:Django默认的
request对象没有customer属性,除非你自行实现了中间件绑定,否则直接调用会抛出属性不存在异常 - 命名不规范:
context_object_name设为customers,但实际存储的是AccountHolder交易记录对象,容易造成逻辑混淆
具体实现步骤
第一步:配置URL传参
首先需要在路由中添加客户ID参数,用于指定要筛选的客户,示例urls.py配置:
from django.urls import path from .views import CustomerDetail urlpatterns = [ # 路径中带入要查询的客户ID参数 path('customer/<int:customer_id>/transactions/', CustomerDetail.as_view(), name='customer_transactions'), ]
第二步:重写视图的get_queryset方法
直接重写ListView的get_queryset方法实现筛选,这是Django通用类视图做数据过滤的标准实现方式,修改后的views.py代码:
from django.shortcuts import get_object_or_404 from django.views.generic import ListView from .models import AccountHolder, Customer class CustomerDetail(ListView): model = AccountHolder context_object_name = 'transactions' # 改名为符合内容的命名 template_name = 'customertransaction.html' def get_queryset(self): # 从URL参数中获取客户ID customer_id = self.kwargs.get('customer_id') # 校验客户是否存在,不存在返回404 customer = get_object_or_404(Customer, id=customer_id) # 返回筛选后的该客户的所有交易记录 return super().get_queryset().filter(customer=customer)
特殊场景:登录用户仅能查看自己的交易记录
如果你的需求是当前登录的用户只能查看自己关联的交易记录,需要先在Customer模型中添加和Django内置User表的关联字段:
# models.py 中Customer类新增字段 from django.contrib.auth.models import User class Customer(models.Model): # 原有字段保留 user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='customer_profile') name = models.CharField(max_length=100) age = models.IntegerField() address = models.CharField(max_length=200) number = models.IntegerField(null=True, blank=True)
此时视图的get_queryset可以直接按登录用户筛选:
def get_queryset(self): return super().get_queryset().filter(customer__user=self.request.user)
注意事项
- 如果确实是通过自定义中间件将客户对象绑定到了
request.customer,直接将上面筛选条件里的customer替换为self.request.customer即可 - 模板中直接遍历
transactions变量就能拿到当前客户的所有交易记录
内容的提问来源于stack exchange,提问作者Lebu4982
相关产品推荐
相关产品推荐

