2024-06-07 19:23:30 发布
网友
Django视图指向一个函数,如果只想更改一点功能,这可能是一个问题。是的,我可以有一百万个关键字参数,甚至更多的if语句在函数中,但我想更多的是面向对象的方法。
例如,我有一个显示用户的页面。这个页面与显示一个组的页面非常相似,但它仍然与仅仅使用另一个数据模型不太相似。小组也有成员等。。。
一种方法是将视图指向类方法,然后扩展该类。有人尝试过这种方法或有其他想法吗?
如果只是显示模型中的数据,为什么不使用Django Generic Views?它们的目的是让您可以轻松地显示模型中的数据,而不必编写自己的视图,也不必编写关于将URL参数映射到视图、获取数据、处理边缘情况、呈现输出等的内容
我需要使用基于类的视图,但我希望能够在URLconf中使用类的全名,而不必总是在使用视图类之前实例化它。帮助我的是一个非常简单的元类:
class CallableViewClass(type): def __call__(cls, *args, **kwargs): if args and isinstance(args[0], HttpRequest): instance = super(CallableViewClass, cls).__call__() return instance.__call__(*args, **kwargs) else: instance = super(CallableViewClass, cls).__call__(*args, **kwargs) return instance class View(object): __metaclass__ = CallableViewClass def __call__(self, request, *args, **kwargs): if hasattr(self, request.method): handler = getattr(self, request.method) if hasattr(handler, '__call__'): return handler(request, *args, **kwargs) return HttpResponseBadRequest('Method Not Allowed', status=405)
我现在既可以实例化视图类,也可以将实例用作视图函数,或者我可以简单地将URLconf指向我的类,让元类为我实例化(并调用)视图类。这是通过检查__call__的第一个参数来实现的——如果它是一个HttpRequest,那么它必须是一个实际的HTTP请求,因为试图用HttpRequest实例实例化视图类是毫无意义的。
__call__
HttpRequest
class MyView(View): def __init__(self, arg=None): self.arg = arg def GET(request): return HttpResponse(self.arg or 'no args provided') @login_required class MyOtherView(View): def POST(request): pass # And all the following work as expected. urlpatterns = patterns('' url(r'^myview1$', 'myapp.views.MyView', name='myview1'), url(r'^myview2$', myapp.views.MyView, name='myview2'), url(r'^myview3$', myapp.views.MyView('foobar'), name='myview3'), url(r'^myotherview$', 'myapp.views.MyOtherView', name='otherview'), )
(我在http://djangosnippets.org/snippets/2041/贴了一个片段)
我创建并使用了自己的泛型视图类,定义了__call__以便类的实例是可调用的。我真的很喜欢它;虽然Django的泛型视图允许通过关键字参数进行一些定制,但是OO泛型视图(如果它们的行为被分割成许多单独的方法)可以通过子类化进行更细粒度的定制,这样我就可以少重复自己的工作了。(我厌倦了在需要调整Django的通用视图不允许的地方重写相同的create/update视图逻辑)。
我在djangosnippets.org贴了一些代码。
我看到的唯一真正的缺点是内部方法调用的激增,这可能会在一定程度上影响性能。我不认为这有什么关系;Python代码执行很少会成为web应用程序中的性能瓶颈。
更新:Django自己的generic views现在是基于类的。
更新:FWIW,自撰写此答案以来,我已更改了对基于类的视图的看法。在将它们广泛应用于几个项目之后,我觉得它们往往会导致编写出令人满意的枯燥代码,但很难在以后阅读和维护,因为功能分布在许多不同的地方,而子类非常依赖于超类和混合的每个实现细节。我现在觉得TemplateResponse和视图装饰器是分解视图代码的更好的方法。
如果只是显示模型中的数据,为什么不使用Django Generic Views?它们的目的是让您可以轻松地显示模型中的数据,而不必编写自己的视图,也不必编写关于将URL参数映射到视图、获取数据、处理边缘情况、呈现输出等的内容
我需要使用基于类的视图,但我希望能够在URLconf中使用类的全名,而不必总是在使用视图类之前实例化它。帮助我的是一个非常简单的元类:
我现在既可以实例化视图类,也可以将实例用作视图函数,或者我可以简单地将URLconf指向我的类,让元类为我实例化(并调用)视图类。这是通过检查
__call__
的第一个参数来实现的——如果它是一个HttpRequest
,那么它必须是一个实际的HTTP请求,因为试图用HttpRequest
实例实例化视图类是毫无意义的。(我在http://djangosnippets.org/snippets/2041/贴了一个片段)
我创建并使用了自己的泛型视图类,定义了
__call__
以便类的实例是可调用的。我真的很喜欢它;虽然Django的泛型视图允许通过关键字参数进行一些定制,但是OO泛型视图(如果它们的行为被分割成许多单独的方法)可以通过子类化进行更细粒度的定制,这样我就可以少重复自己的工作了。(我厌倦了在需要调整Django的通用视图不允许的地方重写相同的create/update视图逻辑)。我在djangosnippets.org贴了一些代码。
我看到的唯一真正的缺点是内部方法调用的激增,这可能会在一定程度上影响性能。我不认为这有什么关系;Python代码执行很少会成为web应用程序中的性能瓶颈。
更新:Django自己的generic views现在是基于类的。
更新:FWIW,自撰写此答案以来,我已更改了对基于类的视图的看法。在将它们广泛应用于几个项目之后,我觉得它们往往会导致编写出令人满意的枯燥代码,但很难在以后阅读和维护,因为功能分布在许多不同的地方,而子类非常依赖于超类和混合的每个实现细节。我现在觉得TemplateResponse和视图装饰器是分解视图代码的更好的方法。
相关问题 更多 >
编程相关推荐