4

我正在尝试在 Django 中重构一个相当庞大的视图函数。有太多的变量浮动,这是一个巨大的功能。

理想情况下,我想将视图模块化为逻辑函数。但是,我必须传递函数上下文才能轻松访问变量。

例如:

def complex_view(request, slug):
    some complex logic which creates variable abc ...
    ...
    some more complex logic which uses variable abc ...
    ...
    etc.

应该变成这样:

def complex_view(request, slug):
    process_X()
    ...somehow pass variables and context to next function...
    process_Y()
    ... 
    etc.

def process_X():
    ...

def process Y():
    ...

我可以想到一些方法来做到这一点,其中一些在这个页面中被指出:http: //mail.python.org/pipermail/tutor/2009-February/067506.html

一种。在主视图中定义的子功能。这看起来很笨拙,因为很难分辨哪些变量是共享的,哪些不是。

湾。locals()作为字典传入。这也是很麻烦的,因为现在有两种不同的访问变量的方法:xyzcontextDict['xyz']. 并且您必须在 call 中使用一个,并且在堆栈上使用Nnext in call 。N+1

C。蛮力将所有变量传递给每个函数调用并返回相关的变量。当涉及很多变量时,这会变得非常乏味。

d。在 C++/C# 中,我会简单地创建一个类MyComplexViewContext,定义所有共享变量,并创建成员函数来完成这项工作。然后,您可以使用self.xyz该类中的所有内容。我想我也可以在 Python 中使用这种方法。不确定这是否是最好的方法。

您对在 Python/Django 中执行此操作的首选方式有何看法?

4

2 回答 2

10

我喜欢 (d) - 为它创建一个类,并使用成员函数来完成这项工作。

在 Django 中,视图只是一个接受 HTTPRequest 对象的“可调用”对象,以及您的 URL 路由传递给它的任何其他参数。

Python 类可以像函数一样被调用,如果你__call__在它们上定义一个方法,就像这样:

class MyView(object):
    def __call__(self, request, slug)
        # do stuff here

    def helper_method(self):
        # etc.

然后你可以在你的urls.py文件中命名这个类,它会像任何其他 python 函数一样被调用。

这样做还可以让您将类似的视图转换为对象实例:

class MyView(object):
    def __init__(self, parameters):
        # initialize instance

    def __call__(self, request, slug):
        # main view code goes here

first_view = MyView("some parameter")
second_view = MyView("some other parameter") # creates second object instance

在 urls.py 中,引用对象(而不是类)——对象也可以像函数一样被调用。

其他技巧是使用继承来定义相似的视图,或者为基类中的许多相似视图提供一些通用功能,然后专门的视图类从这些视图类继承。

您可以查看Simon Willison 的幻灯片以了解更多详细信息,或者查看此片段以获取具体示例

于 2010-01-11T21:18:18.380 回答
0

我可以建议使用类似于 d) 的东西,如下所示:

class ComplexView_SharedVariables:
  # Shared variables (to be used as instance variables, not class variables!)
  a = "somevalue"
  b = ...
  c = ...

class ComplexView_Methods1:
  ... some functionality ...

class ComplexView_Methods2:
  ... some more functionality ...

class ComplexView_All(ComplexView_SharedVariables, ComplexView_Methods1, ComplexView_Methods2):
  # This class puts together all functionality and shared variables
  pass

使用此过程,您甚至可以将类拆分为不同的文件(如果 Django 可以,我没有经验)。

于 2010-01-11T21:20:12.710 回答