假设有Model:Poke和Card,其中,Poke是Card的外键。我们的url有这样的情况,poke/2/card/1,也就是ID为2的poke中的第1个card,我们需要在url中获取传入的2和1,我们使用类视图来完成。
首先DtailView中,其中的get_objet()方法会取得url中传递进来的参数来获取某个object。比如,poke/2,则get_object()会通过Poke模型中pk=2,(其中pk是DetailView中默认的命名组,我们可以重写它,拓展它,就像下面一样)来获取对应的某个Poke。
那,怎么获取那个2呢。
查看源码,在SingleObjectMixin的类属性中,有
pk_url_kwarg = 'pk'
而get_object()方法中,有:
def get_object(self, queryset=None):
"""
Returns the object the view is displaying.
By default this requires `self.queryset` and a `pk` or `slug` argument
in the URLconf, but subclasses can override this to return any object.
"""
# Use a custom queryset if provided; this is required for subclasses
# like DateDetailView
if queryset is None:
queryset = self.get_queryset()
# Next, try looking up by primary key.
pk = self.kwargs.get(self.pk_url_kwarg, None)
slug = self.kwargs.get(self.slug_url_kwarg, None)
if pk is not None:
queryset = queryset.filter(pk=pk)
从get方法可以看出,pk就是get_object()方法用来filter我们得到的queryset参数。
而pk这个变量,是通过kwargs的get方法得到,其中pk_url_kwarg = 'pk',也就是说,pk = self.kwargs.get(self.pk_url_kwarg, None)是取得url中,传入参数的命名组为pk的值,并且传递给本地变量pk。所以嘛,要取得从任何从url中传入的参数,只要使用kwargs.get(命名组,None),命名组是url中的定义的,就OK了。
所以,类似于这样的url:
url(r'^poke/(?P
实际url,如
poke/1/card/2
我们在我们的类视图Cardinfo中,可以这么做
class CardInfo(PokeInfo):
model=Card
context_object_name='information'
template_name='cardspace/card.html'
pk_poke_kwargs='poke_pk'
def get_object(self,queryset=None):
cnum=int(self.kwargs.get(self.pk_url_kwarg,None))
pnum=int(self.kwargs.get(self.pk_poke_kwargs,None))
query=self.get_queryset()
try:
obj=query[pnum-1].cards.all()[cnum-1]
except IndexError:
raise Http404
return obj
def get_context_data(self,**kwargs):
context=DetailView.get_context_data(self,**kwargs)
return context
其中,pk_poke_kwargs是我们自己定义的的第二个参数传入的url命名组,这个名字是随意取的,但是值一定要和url中传入的命名组一致
num=int(self.kwargs.get(self.pk_url_kwarg,None))是我们按照django默认的取参数方法,取得url中命名组为pk的参数,得到2,则cnum=2
之后,我们这样获取命名组中poke_pk的值:
pnum=int(self.kwargs.get(self.pk_poke_kwargs,None))
这样就OK了