DetailView 方法的参数和 pk_url_kwarg 的用法

Nep*_*nat 3 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
Run Code Online (Sandbox Code Playgroud)

1.) 为什么这门课的讲师*argsget_context_data方法中使用,而在django的源代码中get_context_data却只有**kwargs

get_context_data 方法的源代码

2.) 此外get_object方法。为什么他用*argsand**kwargs但是Django中的方法只有一个queryset参数

get_object 方法的源代码

3.) 而我的最后一个问题,为什么不只是使用pk_url_kwarg变量将名称更改pkrest_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
Run Code Online (Sandbox Code Playgroud)

Ala*_*air 5

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

您是正确的,您可以使用pk_url_kwarg而不是覆盖get_object. 本pk_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'
Run Code Online (Sandbox Code Playgroud)