35

i am trying to call a class based view and i am able to do it, but for some reason i am not getting the context of the new class that i am calling

class ShowAppsView(LoginRequiredMixin, CurrentUserIdMixin, TemplateView):
    template_name = "accounts/thing.html"



    @method_decorator(csrf_exempt)
    def dispatch(self, *args, **kwargs):
        return super(ShowAppsView, self).dispatch(*args, **kwargs)

    def get(self, request, username, **kwargs):
        u = get_object_or_404(User, pk=self.current_user_id(request))

        if u.username == username:
            cities_list=City.objects.filter(user_id__exact=self.current_user_id(request)).order_by('-kms')
            allcategories = Category.objects.all()
            allcities = City.objects.all()
            rating_list = Rating.objects.filter(user=u)
            totalMiles = 0
            for city in cities_list:
                totalMiles = totalMiles + city.kms

        return self.render_to_response({'totalMiles': totalMiles , 'cities_list':cities_list,'rating_list':rating_list,'allcities' : allcities, 'allcategories':allcategories})


class ManageAppView(LoginRequiredMixin, CheckTokenMixin, CurrentUserIdMixin,TemplateView):
    template_name = "accounts/thing.html"

    def compute_context(self, request, username):
        #some logic here                        
        if u.username == username:
            if request.GET.get('action') == 'delete':
                #some logic here and then:
                ShowAppsView.as_view()(request,username)

What am i doing wrong guys?

psychok7
  • 5,373
  • 9
  • 63
  • 101
  • 1
    What is this supposed to be doing? What are you hoping to achieve by simply calling that view? I guess you probably need to return the result of calling it, but since `compute_context` is a non-standard method it's hard to be sure. – Daniel Roseman Feb 19 '13 at 11:47
  • i am kind of "refreshing" my page so i am recalling my previous page with some new context data – psychok7 Feb 19 '13 at 11:50
  • i am returning return self.render_to_response(self.compute_context(request,username)) – psychok7 Feb 19 '13 at 11:50
  • this works if i call it from the urls but from another view its not workin – psychok7 Feb 19 '13 at 11:50
  • 1
    But you haven't explained what you are hoping to happen by simply calling that view. You call it and then throw away the response: as I said, did you actually want to return it? Or maybe you meant to call its compute_context method and do something with the values it returns? As it is, that line is completely pointless. – Daniel Roseman Feb 19 '13 at 11:57
  • i edited my code, how am i throwing my response away? – psychok7 Feb 19 '13 at 12:18
  • 2
    Because you call it *and then don't do anything with the result*. – Daniel Roseman Feb 19 '13 at 12:39
  • You should really think about making the so called business logic reusable. Views should be just entry points for external visitors (read: HTTP clients) and not something you call internally. – Tomasz Zieliński Jul 29 '14 at 10:15

2 Answers2

57

Instead of

ShowAppsView.as_view()(self.request)

I had to do this

return ShowAppsView.as_view()(self.request)
arulmr
  • 8,620
  • 9
  • 54
  • 69
psychok7
  • 5,373
  • 9
  • 63
  • 101
  • 6
    I found that if you do ShowAppsView.as_view()(request, *args, **kwargs) it is actually possible to get the args and kwargs through to the get_context_data method with the ContextMixin, where they appear as self.args and self.kwargs. This is very useful for overriding this method and adding to the context for, say, a form. – Sven Apr 10 '14 at 22:33
  • 1
    I find this is useful in function views also. That's with above code i am able to call class based view from function views. – Ajeeb.K.P Jan 21 '15 at 08:47
  • Does not work anymore.. as of now the only option I see is to use `django.test.Client` – dnit13 Mar 09 '19 at 23:06
  • 3
    but when using DRF it throws ```The `request` argument must be an instance of `django.http.HttpRequest`, not `rest_framework.request.Request`.``` – Yash Agrawal Jun 17 '20 at 17:50
1

Things get more complicated when you start using multiple inheritance in python so you could easily be trampling your context with that from an inherited mixin.

You don't quite say which context you are getting and which one you want (you're not defining a new context), so it's difficult to completely diagnose, but try rearranging the order of your mixins;

class ShowAppsView(LoginRequiredMixin, CurrentUserIdMixin, TemplateView):

this implies that LoginRequiredMixin will be the first class to inherit from, and so it will take precedence over the others if it has the attribute you're looking for - if it hasn't then python will look in CurrentUserIdMixin and so on.

If you want to be really sure that you get the context that you're after, you could add an override like

def get_context(self, request):
    super(<my desired context mixin>), self).get_context(request)

to ensure that the context you get is the one from the mixin that you want.

* Edit * I don't know where you've found compute_context but it's not a django attribute so will only get called from ShowAppsView.get() and never in ManageAppView.

danodonovan
  • 19,636
  • 10
  • 70
  • 78
  • i edited my code above and took out the compute_context but its still not working. Should i inherit ManageAppView from ShowAppSview in order to access the method? – psychok7 Feb 19 '13 at 12:06
  • ditto @Daniel Roseman If `compute_context` is what you want returned, you will need it. It's non-standard, so maybe should be in `get_context` or similar. I wasn't offering a complete fix, but a route for exploration / investigation. – danodonovan Feb 19 '13 at 12:12