Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Arguments of DetailView methods and usage of pk_url_kwarg

Tags:

python

django

I'm currently watching a course on Django and wondering about the following code:

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.) Why is the instructor of this course using *args in the get_context_data method but in the source code of django the get_context_data only has **kwargs

Source Code of get_context_data method

2.) Furthermore the get_object method. Why does he use *args and **kwargs but the method in Django only has a queryset argument

Source Code of get_object method

3.) And my last question, why isn't the just using the pk_url_kwarg variable to change the name of pk to rest_id

I rewrote this code an it still works but I'm really new to Django and I'm not sure if misunderstood something.

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
like image 841
Nepo Znat Avatar asked Sep 21 '25 03:09

Nepo Znat


1 Answers

As a Django user, def get_context_data(self, *args, **kwargs): and def get_object(self, *args, **kwargs): look unusual to me. The code will work because the same args and kwargs are passed to super(). You could argue that it makes the code more robust because it will still work if Django changes the signature in a future version. However I would prefer to use the same signatures as the parent class.

You are correct that you could use pk_url_kwarg instead of overriding get_object. The pk_url_kwarg should be the name of the kwarg in the URL pattern, so in this case it should be pk_url_kwarg = 'rest_id'. The advantage of pk_url_kwarg is that it simplifies the code. The disadvantage is that it's less obvious how the object is being fetched if you're not familiar with Django's class-based-views.

There's a couple more changes you could make. Instead of queryset = Restaurant.objects.all() you can simply set model, because get_queryset defaults to self.model.objects.all().

Finally, the get_context_data method doesn't do anything apart from printing, so I would remove it entirely once I'd finished debugging.

Putting that together, you get:

class RestaurantDetailView(DetailView):
    model = Restaurant
    pk_url_kwarg = 'rest_id'
like image 162
Alasdair Avatar answered Sep 22 '25 16:09

Alasdair