DetailView方法的参数和pk_url_kwarg的用法

时间:2018-04-20 10:40:51

标签: python django

我正在观看关于Django的课程并想知道以下代码:

class RestaurantDetailView(DetailView):
    queryset = Restaurant.objects.all()

    def get_context_data(self, *args, **kwargs):
        context = super().get_context_data(*args, **kwargs)
        return context

    def get_object(self, *args, **kwargs):
        rest_id = self.kwargs.get('rest_id')
        obj = get_object_or_404(Restaurant, id=rest_id)
        return obj

1。)为什么本课程的讲师在*args方法中使用get_context_data,但在django的源代码中,get_context_data只有**kwargs

Source Code of get_context_data method

2。)此外还有get_object方法。为什么他使用*args**kwargs,但Django中的方法只有queryset参数

Source Code of get_object method

3。)我的上一个问题,为什么不只是使用pk_url_kwarg变量将pk的名称更改为rest_id

我重写了这段代码,它仍然有效,但我对Django来说真的很新,我不确定是否误解了一些东西。

class RestaurantDetailView(DetailView):
    pk_url_kwarg = 'rest_id'
    queryset = Restaurant.objects.all()

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        return context

1 个答案:

答案 0 :(得分:3)

作为Django用户,def get_context_data(self, *args, **kwargs):def get_object(self, *args, **kwargs):看起来很不寻常。代码将起作用,因为相同的args和kwargs传递给super()。您可以争辩说,它使代码更加健壮,因为如果Django在未来版本中更改签名,它仍然可以工作。但是我更喜欢使用与父类相同的签名。

您是正确的,可以使用pk_url_kwarg而不是覆盖get_objectpk_url_kwarg应该是URL模式中kwarg的名称,因此在这种情况下它应该是pk_url_kwarg = 'rest_id'pk_url_kwarg的优点是它简化了代码。缺点是,如果您不熟悉Django的基于类的视图,那么对象的获取方式就不那么明显了。

您可以进行更多更改。您只需设置queryset = Restaurant.objects.all(),而不是model,因为get_queryset默认为self.model.objects.all()

最后,除了打印之外,get_context_data方法还没有做任何事情,所以一旦我完成调试,我就会完全删除它。

把它们放在一起,你得到:

class RestaurantDetailView(DetailView):
    model = Restaurant
    pk_url_kwarg = 'rest_id'