基于类的视图的Django的as_view()语法一直困扰着我。基本上,我厌倦了为我想要使用的每个基于类的视图执行my_view = MyView.as_view()(或者在每个url conf的每一行中使用as_view()我使用基于c的视图)。我认为类装饰器将是一种更清晰的方式来实现这一点,我想弄清楚如何实现这一点,为我自己的代码和共享django片段,以防其他人感兴趣。所以我的问题是:是否有合理的方法来实现“as_view”装饰器,以便以下代码可以正常运行?
@as_view(my_view)
class MyView(View):
pass
基本上相当于:
class MyView(View):
pass
my_view = MyView.as_view()
谢谢,这也有助于我学习python的高级功能(即装饰器)。
本
答案 0 :(得分:2)
我想到的一种方法是让类装饰器只是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
非常简单易读,所以我坦率地更喜欢自己。