假设有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<poke_pk>\d+)/card/(?P<pk>\d+)/$',CardInfo.as_view(),name='cardinfo'),
实际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了