Search code examples
djangodjango-class-based-viewsdjango-generic-views

How do I reference a parameter from a second model object inside a DeleteView to pass to my get_success_url?


My question is:

  • how do I reference a parameter from an object other than the model the DeleteView is based on (in this case the <'list_pk'> param) from the List object instance

  • and pass it from my DeleteView to my get_success_url reverse method...

  • In order to successfully render the get_success_url template?

My get_success_url is this:

url(r'^(?P<username>[a-zA-Z0-0_.-]+)/(?P<list_pk>\d+)/$', 
    views.list_detail, 
    name='listdetail'),

My DeleteView url is:

url(r'^(?P<username>[a-zA-Z0-0_.-]+)/(?P<list_pk>\d+)/delete_item/(?P<pk>\d+)$', 
views.DeleteItemView.as_view(), 
name='deleteitem'),

My DeleteView code is the following:

class DeleteItemView(LoggedInMixin, DeleteView):
model = Item

def get_success_url(self):
    return reverse_lazy(
        'lists:listdetail', 
        kwargs = {'username': self.request.user, 
                  ??'list_pk': self.request.user.list.id ??})

list_pk is the parameter I need to pass into the success_url. It is from a related but separate List() object. I.e. a List has many Items - an Item has a List.

self.request.user passes the username parameter no problem. I have tried many permutations to capture the list_pk parameter to no avail. The current attempt surrounded by ?? ?? is the one that logically makes sense to me, but I get an error saying that the User object has no list attribute.

I'm new to class-based views so I'm sure there is an obvious fix for this, but I haven't found it yet.

Another of my attempts centered around using get_context_data to pass in the List object, extract the particular list_pk that I need and then reference that in success_url, I haven't included that attempt here however, as it didn't work.

Any help is much appreciated. Thanks.


Solution

  • In a class based view, as in function based views, url parameters are passed as keyword arguments. To access them in a CBV, use self.kwargs.get('some_parameter').

    class DeleteItemView(LoggedInMixin, DeleteView):
    model = Item
    
        def get_success_url(self):
            list_pk= self.kwargs.get('list_pk')
            # I don't see why you would need a lazy inside a method...
            return reverse('lists:listdetail', 
                           kwargs = {'username': self.request.user, 'list_pk': list_pk})