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

时间:2022-03-29 13:23:41

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:

我在一个基于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

When I run this it says name 'self' is not defined

当我运行这个时,它说的是name 'self'没有定义。

If I try def get_player_stats(self, request): it says missing 1 required positional argument: 'request'

如果我尝试def get_player_stats(self, request):它说缺少一个必需的位置参数:'request'

If I try def get_player_stats(request, self): it says missing 1 required positional argument: 'self'

如果我尝试def get_player_stats(request, self):它说缺少一个必需的位置参数:'self'

How can I call get_team_stats from get_player_stats?

如何从get_player_stats调用get_team_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:

P。S:我将get_player_stats定义为一个URL路径,如下所示:

url('score/get_player_stats', views.ScoreView.get_player_stats)

Then I call it using $.ajax with url: '/score/get_player_stats'

然后我用$调用它。ajax与url:‘/分/ get_player_stats’

1 个解决方案

#1


1  

I see here 2 problems:

我在这里看到两个问题:

  1. Misconceptions about class-based views in django
  2. 对django中基于类的视图的误解
  3. Misconceptions about object- and class- methods in python
  4. 对python中的对象和类方法的误解

Let's look in more detail.

让我们看得更详细一些。

1. Django class-based views

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.

这听起来一定很奇怪(特别是对于新手),但是在django中基于类的视图并不意味着要将对象/类的方法绑定到url路由。

More so:

更多:

  • django.urls.path can use only functions of fn(request, *args, **kwargs)

    django.urls。路径只能使用fn的函数(request, *args, *kwargs)

  • Pythonic it's better explicite for self-param makes object-methods unusable for views (at least without "special magic").

    python语言更好地解释了自解析,使得对象方法不能用于视图(至少没有“特殊的魔力”)。

So what the meaning of class-based views?

基于类的视图是什么意思呢?

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

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

In fact it's very simple:

事实上很简单:

  1. class-based view expose class method as_view
  2. 基于类的视图公开类方法as_view
  3. as_view is a high-order function and not used directly in path/url calls.
  4. as_view是一个高阶函数,不直接用于路径/url调用。
  5. as_view constructs actual view function at runtime
  6. as_view在运行时构造实际的视图函数
  7. generated function is not very complicated too. Roughly speaking, it looks for existence of defined get/post/put/head-methods, calls them when they exists and raises exceptions when not exists.
  8. 生成的函数也不是很复杂。粗略地说,它寻找已定义的get/post/put/head方法的存在,在它们存在时调用它们,在不存在时抛出异常。

So you can see that "one does not simply binds methods of class-view to url-routes in django".

因此,您可以看到“一个并不简单地将类视图的方法绑定到django中的url路由”。

It is a tool that can be hardly recommended for general cases, it works good in cases when this inflexibility is desirable.

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

2. object-,class-, static- methods

OK. 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)

让我们看看django 2.0中的一个文件演示。(1.11 - % s /道路/ 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:

简介:

  1. Plain functions are best in general
  2. 一般来说,纯函数是最好的
  3. Object methods are not usable (at least without some "special magic")
  4. 对象方法不可用(至少没有一些“特殊的魔力”)
  5. Class methods: have no problems. But keep in mind that class methods can use only other class methods
  6. 类方法:没有问题。但是请记住类方法只能使用其他类方法
  7. Static methods: OK for using in path/url calls but they can't use other methods of classes
  8. 静态方法:用于路径/url调用,但不能使用类的其他方法
  9. If you really really want to use OOP: you can do it in "django way" - create HOFs that will generate actual views functions at runtime. Look at django.views.generic source code for inspiration
  10. 如果您真的想要使用OOP:您可以使用“django方式”—创建在运行时将生成实际视图函数的HOFs。看看django.views。灵感的通用源代码

...

I hope that must clear things up but questions, critique, corrections - you are welcome!

我希望能把事情弄清楚,但问题、批评、纠正——欢迎你!

#1


1  

I see here 2 problems:

我在这里看到两个问题:

  1. Misconceptions about class-based views in django
  2. 对django中基于类的视图的误解
  3. Misconceptions about object- and class- methods in python
  4. 对python中的对象和类方法的误解

Let's look in more detail.

让我们看得更详细一些。

1. Django class-based views

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.

这听起来一定很奇怪(特别是对于新手),但是在django中基于类的视图并不意味着要将对象/类的方法绑定到url路由。

More so:

更多:

  • django.urls.path can use only functions of fn(request, *args, **kwargs)

    django.urls。路径只能使用fn的函数(request, *args, *kwargs)

  • Pythonic it's better explicite for self-param makes object-methods unusable for views (at least without "special magic").

    python语言更好地解释了自解析,使得对象方法不能用于视图(至少没有“特殊的魔力”)。

So what the meaning of class-based views?

基于类的视图是什么意思呢?

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

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

In fact it's very simple:

事实上很简单:

  1. class-based view expose class method as_view
  2. 基于类的视图公开类方法as_view
  3. as_view is a high-order function and not used directly in path/url calls.
  4. as_view是一个高阶函数,不直接用于路径/url调用。
  5. as_view constructs actual view function at runtime
  6. as_view在运行时构造实际的视图函数
  7. generated function is not very complicated too. Roughly speaking, it looks for existence of defined get/post/put/head-methods, calls them when they exists and raises exceptions when not exists.
  8. 生成的函数也不是很复杂。粗略地说,它寻找已定义的get/post/put/head方法的存在,在它们存在时调用它们,在不存在时抛出异常。

So you can see that "one does not simply binds methods of class-view to url-routes in django".

因此,您可以看到“一个并不简单地将类视图的方法绑定到django中的url路由”。

It is a tool that can be hardly recommended for general cases, it works good in cases when this inflexibility is desirable.

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

2. object-,class-, static- methods

OK. 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)

让我们看看django 2.0中的一个文件演示。(1.11 - % s /道路/ 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:

简介:

  1. Plain functions are best in general
  2. 一般来说,纯函数是最好的
  3. Object methods are not usable (at least without some "special magic")
  4. 对象方法不可用(至少没有一些“特殊的魔力”)
  5. Class methods: have no problems. But keep in mind that class methods can use only other class methods
  6. 类方法:没有问题。但是请记住类方法只能使用其他类方法
  7. Static methods: OK for using in path/url calls but they can't use other methods of classes
  8. 静态方法:用于路径/url调用,但不能使用类的其他方法
  9. If you really really want to use OOP: you can do it in "django way" - create HOFs that will generate actual views functions at runtime. Look at django.views.generic source code for inspiration
  10. 如果您真的想要使用OOP:您可以使用“django方式”—创建在运行时将生成实际视图函数的HOFs。看看django.views。灵感的通用源代码

...

I hope that must clear things up but questions, critique, corrections - you are welcome!

我希望能把事情弄清楚,但问题、批评、纠正——欢迎你!