I have a method inside a django class based view like called get_player_stats. From this method I want to call another method in the same class but I am unable to. Code is like below:
class ScoreView(TemplateView):
def get_player_stats(request):
player_id = request.GET.get(player_id, None)
# compute player stats
#here I want to call like below:
self.get_team_stats(player_id)
def get_team_stats(self, player_id):
#compute team stats
When I run this it says name 'self' is not defined
If I try def get_player_stats(self, request): it says missing 1 required positional argument: 'request'
If I try def get_player_stats(request, self): it says missing 1 required positional argument: 'self'
How can I call get_team_stats from get_player_stats?
This is very frustrating, any help is greatly appreciated
P.S: I call get_player_stats as an ajax call by defining a URL path as below:
url('score/get_player_stats', views.ScoreView.get_player_stats)
Then I call it using $.ajax with url: '/score/get_player_stats'
I see here 2 problems:
class-based views in django object- and class- methods in pythonLet's look in more detail.
It must be sound strange (especially for newcomers) but class-based view in django does not means that you bind methods of objects/classes to url-routes.
More so:
django.urls.path can use only functions of fn(request, *args, **kwargs)
Pythonic it's better explicite for self-param makes object-methods unusable for views (at least without "special magic").
So what the meaning of class-based views?
https://github.com/django/django/blob/2bc014750adb093131f77e4c20bc17ba64b75cac/django/views/generic/base.py#L48
In fact it's very simple:
class-based view expose class method as_viewas_view is a high-order function and not used directly in path/url calls.as_view constructs actual view function at runtimeget/post/put/head-methods, calls them when they exists and raises exceptions when not exists. So you can see that "one does not simply binds methods of class-view to url-routes in django".
It is a tool that can be hardly recommended for general cases, it works good in cases when this inflexibility is desirable.
object-,class-, static- methodsOK. Now the second problem.
Can we call from methods of class-based view other methods?
Yes we can but with some restrictions.
Let's look at one-file demo in django 2.0. (For 1.11 - %s/path/url/g)
from django.urls import path
from django.http import HttpResponse
from django.utils.decorators import classonlymethod
# CASE 1: normal function - OK
def just_a_fun(request, **kwargs):
context = kwargs if kwargs else {"method": "just a function"}
return HttpResponse('method = %(method)s' % context)
class ViewClass(object):
def get(self, request, **kwargs):
return just_a_fun(request, **kwargs)
# CASE 2: Object method - FAIL, not possible to use in `django.url.path`-calls
def om_view(self, request):
return self.get(request, **{"method": "object method"})
# CASE 3: class method - OK
@classmethod
def cm_view(cls, request):
return cls.get(cls, request, **{"method": "class method"})
# CASE 4: static method - FAIL, not possible to call `cls.get` or `self.get`
@staticmethod
def sm_view(request):
self = None # This is a problem with static methods
return self.get(self, request, **{"method": "static method"})
# CASE 5: HOF-view, similar to django.views.generic.View.as_view - OK
@classonlymethod
def as_view(cls, **initkwargs):
def view(request, **kwargs):
self = cls(**initkwargs) # Object construction
self.request = request
self.kwargs = kwargs
return self.get(request, **{"method": "HOF as_view"})
return view
urlpatterns = [
path("just-a-fun", just_a_fun), # OK
path("object-method",
ViewClass.om_view), # Problem: redundant `self` for `path`
path("class-method", ViewClass.cm_view), # OK
path('static-method',
ViewClass.sm_view), # Problem: not possible to call `get`
path('hof-view', ViewClass.as_view()), # OK.
]
Summary:
path/url calls but they can't use other methods of classes django.views.generic source code for inspiration...
I hope that must clear things up but questions, critique, corrections - you are welcome!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With