Django-在基于类的视图中从另一个调用一个类方法

Und*_*ble 3 python django django-views

我有一个基于django类的视图中的方法,称为get_player_stats。我想从该方法中调用同一类中的另一个方法,但无法执行。代码如下:

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
Run Code Online (Sandbox Code Playgroud)

当我运行它时,它说 name 'self' is not defined

如果我尝试def get_player_stats(self, request):missing 1 required positional argument: 'request'

如果我尝试def get_player_stats(request, self):missing 1 required positional argument: 'self'

我怎么打电话get_team_statsget_player_stats

这非常令人沮丧,非常感谢您的帮助

PS:我get_player_stats通过定义如下URL路径将其称为ajax调用:

url('score/get_player_stats', views.ScoreView.get_player_stats)
Run Code Online (Sandbox Code Playgroud)

然后我用$ .ajax与 url: '/score/get_player_stats'

Ale*_* Yu 5

我在这里看到2个问题:

  1. 关于class-based views的误解django
  2. 关于以下方面的误解object-class-方法python

让我们更详细地看。

1. Django基于类的视图

它一定听起来很奇怪(尤其是对于新手而言),但class-based view在django中并不意味着您将objects/ 方法绑定 classesurl-routes。

更是如此:

  • django.urls.path 只能使用以下功能 fn(request, *args, **kwargs)

  • Pythonic it's better explicite for self-param使其object-methods无法使用views(至少在没有“特殊魔术”的情况下)。

那是什么意思class-based views呢?

https://github.com/django/django/blob/2bc014750adb093131f77e4c20bc17ba64b75cac/django/views/generic/base.py#L48

实际上,这非常简单:

  1. class-based view 公开类方法 as_view
  2. as_view是高阶函数,不能直接在 path/ url调用中使用。
  3. as_view 在运行时构造实际的视图函数
  4. 生成的函数也不是很复杂。粗略地说,它看起来对定义的存在get/ post/ put/ head-方法,当他们存在和不存在时引发异常调用它们。

因此,您可以看到“一个不只是将类视图的方法绑定到Django中的url-routes”。

它是一般情况下几乎不推荐使用的工具,在需要这种灵活性的情况下,它会很好地工作。

2 object-class-static-方法

好。现在第二个问题。

我们可以从class-based view其他方法中调用吗?

是的,我们可以但有一些限制。

让我们看一下one-filedjango 2.0 中的演示。(对于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. 
]
Run Code Online (Sandbox Code Playgroud)

摘要:

  1. 普通功能最好
  2. 对象方法不可用(至少没有一些“特殊魔术”)
  3. 类方法:没有问题。但是请记住,类方法只能使用其他类方法
  4. 静态方法:可以在path/ url调用中使用,但不能使用其他类的方法
  5. 如果您真的想使用OOP:可以用“ django方式”进行操作-创建HOF,这些HOF将在运行时生成实际的视图函数。查看django.views.generic源代码以获取灵感

...

我希望除了问题,批评,更正之外,必须清除一切,欢迎您!