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

2024-05-21

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

当我运行这个时它说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_stats from get_player_stats?

这非常令人沮丧,非常感谢任何帮助

PS:我打电话get_player_stats通过定义 URL 路径作为 ajax 调用,如下所示:

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

然后我使用 $.ajax 来调用它url: '/score/get_player_stats'


我在这里看到两个问题:

  1. 关于的误解class-based views in django
  2. 关于的误解object- and class-中的方法python

让我们更详细地看看。

1. Django 基于类的视图

听起来一定很奇怪(尤其是对于新人)但是class-based view在 django 中并不意味着你绑定的方法objects/classes to url-路线。

更是如此:

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

  • Pythonicit'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 https://github.com/django/django/blob/2bc014750adb093131f77e4c20bc17ba64b75cac/django/views/generic/base.py#L48

其实很简单:

  1. class-based view暴露类方法as_view
  2. as_view是一个高阶函数,不直接使用path/url calls.
  3. as_view在运行时构造实际的视图函数
  4. 生成的函数也不是很复杂。粗略地说,它寻找定义的存在get/post/put/head-方法,当它们存在时调用它们,当它们不存在时引发异常。

所以你可以看到“在 django 中,并不是简单地将 class-view 的方法绑定到 url-routes”。

对于一般情况来说,很难推荐使用这种工具,但在需要这种不灵活性的情况下,它效果很好。

2. object-,class-, static- methods

好的。现在第二个问题。

我们可以从以下方法调用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. 
]

Summary:

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

...

我希望这必须澄清问题,但欢迎提出问题、批评、指正!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

随机推荐

  • 打印“\n”或换行符作为终端输出的一部分

    我正在终端上运行 Python 给定一个字符串string abcd n 我想print它以某种方式使换行符 n in abcd n将是可见的而不是转到下一行 我可以做到这一点而不必修改字符串并添加双斜杠 n Use repr https
  • “匹配”语句中的“使用部分移动的值”错误

    My code fn main let mut messages vec let msg Message Write message msg to string match msg Message Write message gt prin
  • Spring事务不回滚

    我有这样的事情 Service Transactional public class ServiceA Autowired SomeDAO1 dao1 Autowired ServiceB serviceB public void meth
  • jQuery 的 ondragstart 事件

    我一直在尝试使用 Javascript 拖放 API var file document getElementById file file addEventListener dragstart function evt evt dataTr
  • 如何让flutter应用程序在android导航栏后面绘制并使导航栏完全透明?

    我想让我的 Flutter 应用程序占据 Android 中的整个屏幕 同时仍然显示状态栏和导航栏 并且两者都是透明的 以实现全屏 如下所示iOS https codelabs developers google com codelabs
  • 使用 Javascript/JQuery 的 JSON 对象的差异

    我在 Javascript 中有两个 JSON 对象 除了数值之外 它们都是相同的 它看起来像这样 var data eth0 Tx 4136675 Rx 13232319 eth1 Tx 4 Rx 0 lo Tx 471290 Rx 47
  • 三星 Galaxy Note II - 逗号作为数字键盘小数分隔符

    我正在尝试使用逗号作为三星 Galaxy Note II 上数字键盘的小数分隔符 我已经在其他设备 Moto X rooted Samsung GS4 上测试了我的应用程序 如果我从设备的系统设置中更改语言 它们的小键盘具有正确的分隔符 三
  • 在 IOS 中通过 Linking.openURL React Native 打开设置

    我想从我的应用程序打开 ios 设置应用程序 设置目标是 settings gt notification gt myapp 打开和关闭推送通知 有一些关于如何链接到设置的文档 但我不知道如何打开深层链接 通知 gt myapp 我怎样才能
  • 修改二维数组的malloc策略,使malloc成功

    我们最近收到一份报告 称我们的应用程序偶尔会无法运行 我找到了问题代码 struct ARRAY2D long col int numRows 800000 int numCols 300 array ARRAY2D malloc numR
  • Notepad++ - 使函数“可点击”?

    我只是想这可能有用 但我找不到办法 在 Notepad 中 有没有一种方法可以使函数名称 可单击 即使它们成为链接 这样如果您单击它们 它会自动将您带到其定义 最好是跨整个代码库 目前还没有插件提供可直接单击的函数名称 但您可以尝试使用 S
  • 使用 CSS 删除不需要的表格单元格边框

    我有一个奇怪且令人沮丧的问题 对于简单的标记 table thead tr th 1 th th 2 th th 3 th tr thead tbody tr td a td td b gt td td c td tr tr class o
  • R 颜色 - 许多独特的颜色仍然很漂亮

    我很好奇你是否有一些关于 R 中颜色酿造的技巧 对于许多独特的颜色 在某种程度上图形仍然好看 我需要相当数量的独特颜色 至少 24 种 可能需要更多 50 种 用于堆叠区域图 所以不是热图 渐变颜色不起作用 我发现了 viridis 它的调
  • 如何在 Java 中创建“事件驱动”后台线程?

    我喜欢简单的invokeLater 用于将工作单元发送到 AWT EDT 最好有一个类似的机制来向后台线程 例如 SwingWorker 发送工作请求 但据我了解 这些机制没有任何类型的事件排队和调度机制 而这正是 invokeLater
  • nvd3 格式化日期始终返回 1970-01-01

    我正在尝试使用构建折线图nvd3 for d3js但我在 x 轴上使用日期域时遇到了一些问题 这是我的代码 data lineChart key key1 values x 2014 04 20 y 6 x 2014 04 13 y 5 x
  • Android:对文本后面的图像使用alignBaseline

    下面是一个 TextView 后跟一个包含在relativelayout中的imageview 我试图使图像的底部与文本的基线对齐 当我对图像使用alignBaseline时 引用TextView 图像的顶部与文本的基线对齐 而不是底部 我
  • groupingBy 之后对列表进行排序

    我想知道流 或收集器 中是否已经有一个已实现的功能 该功能已将列表排序为值 例如 以下代码都生成按性别分组的人员列表 并按年龄排序 第一个解决方案有一些开销排序 并且看起来有点邋遢 第二种解决方案需要对每个人进行两次检查 但效果很好 首先排
  • 如何将 SQL Server 中同一表中的一列插入到另一列中

    我需要将一列的数据插入到同一个表中的另一列中 谁能告诉我这个怎么写 Thanks UPDATE table SET col 2 col 1
  • Overflow:auto 导致子 DIV 的绝对元素消失

    我有一个 div A 我在其中设置了overflow auto 现在在该 div 内 我有两个 div 父 div B 设置为position relative和子 div C 是position absolute 现在的问题是 设置ove
  • 空指针和void指针有什么区别?

    有什么区别空指针 A空指针 空指针是一个特殊保留的value的一个指针 任何类型的指针都有这样的保留值 形式上 每个特定的指针类型 int char 等 有其自己专用的空指针值 从概念上讲 当指针具有空值时 它并不指向任何地方 空指针是一个
  • Django - 在基于类的视图中从另一个类方法调用一个类方法

    我在基于 django 类的视图中有一个方法 例如称为get player stats 我想从这个方法中调用同一个类中的另一个方法 但我无法这样做 代码如下 class ScoreView TemplateView def get play