Django基于类的视图的as_view()语法一直困扰着我。基本上,我厌倦了必须为要使用的每个基于类的视图执行my_view = MyView.as_view()(或在我使用基于c的视图的每个url conf的每一行中都放入as_view())。我认为类装饰器将是实现此目的的一种更清洁的方法,并且我试图找出如何实现这一点(对于我自己的代码),并在他人感兴趣的情况下共享django代码段。所以我的问题是:是否有合理的方法来实现“ as_view”装饰器,以便使以下代码起作用?

@as_view(my_view)
class MyView(View):
   pass


这基本上等同于:

class MyView(View):
   pass
my_view = MyView.as_view()


谢谢,这也有助于我学习python的高级功能(即装饰器)。

最佳答案

我想到的一种方法是让类装饰器只是setattr一些对象,其中将包含您要定义的所有as_views。然后,您可以在urls.py中使用它

import re

class Views(object):
    """Empty object for holding as_view method"""
views = Views()

def convert_name(name):
    """convert CapWords into cap_words"""
    return name[0].lower() + re.sub(r'([A-Z])', lambda m:"_" + m.group(0).lower(), name[1:])

def as_view(views):
    """Adds decorated class-based views' as_view methods to views container"""
    def decorator(cls):
        name = convert_name(cls.__name__)
        setattr(views, name, cls.as_view)
        return cls
    return decorator


然后在您的views.py中,您将像这样使用它:

from as_view_decorator import views, as_view

@as_view(views)
class MyView(View):
    ....


..和MyView.as_view将作为views存储在views.my_view对象上。

您还可以在views.py中执行以下操作:

from as_view_decorator impor as_view
import sys; mod = sys.modules[__name__]

@as_view(mod)
class MyView(View):
    ...


这会将my_view设置为views模块上的属性。然后,您可以在urls.py中:

from app.views import my_view

urlpatterns = patterns('',
    url(r'^$', my_view()),
)


我认为my_view = MyView.as_view十分简单易读,因此坦率地说我更喜欢自己。

关于python - 可以在装饰器中实现as_view()(基于类的 View )吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7086272/

10-16 19:43