如何在Django类视图中获取urls.py传递的store_domainKey参数
Django类视图(CBV)中获取URL参数并实现原FBV的逻辑
你遇到的报错核心原因是get_queryset方法的签名写错了——Django的DetailView里,get_queryset默认只接收self一个参数,你额外添加的store_domainKey参数会导致框架调用时参数不匹配,所以才会抛出"missing 1 required positional argument"的错误。
要在CBV里复刻你之前FBV的逻辑其实很简单:Django会自动把URL中捕获的命名参数存入视图实例的self.kwargs字典中,你直接从这里取值即可。下面给你两种符合CBV设计思路的实现方式:
方式一:重写get_object方法(更贴合DetailView定位)
因为DetailView本身就是用来获取单个对象的,重写get_object方法直接返回目标对象,和你FBV里用get_object_or_404的逻辑完全一致:
from django.shortcuts import get_object_or_404 from django.views.generic.detail import DetailView from .models import Store class StoreDetailView(DetailView): model = Store template_name = 'boutique/detail.html' def get_object(self, queryset=None): # 从URL参数中取出store_domainKey store_domain_key = self.kwargs.get('store_domainKey') # 和你FBV里的逻辑完全一致,找不到对象就返回404 return get_object_or_404(Store, domainKey=store_domain_key)
方式二:重写get_queryset方法
如果你更倾向于通过过滤查询集让DetailView自动匹配对象,可以这么写:
from django.views.generic.detail import DetailView from .models import Store class StoreDetailView(DetailView): model = Store template_name = 'boutique/detail.html' def get_queryset(self): store_domain_key = self.kwargs.get('store_domainKey') # 返回过滤后的查询集,DetailView会从中自动获取单个对象 return Store.objects.filter(domainKey=store_domain_key)
额外说明
- 无论用哪种方式,都不要给
get_queryset或get_object额外添加参数,所有URL里的命名参数都从self.kwargs中获取; - 第二种方式中,如果过滤后的查询集包含多个对象,DetailView会抛出
MultipleObjectsReturned异常,这和你用get_object_or_404的行为完全一致(因为get_object_or_404底层用的是get()方法,多对象也会报错)。
内容的提问来源于stack exchange,提问作者Jay P.
相关产品推荐
相关产品推荐

