Django中的类视图

wsed 发布于 2018-02-05 django 最后更新 2018-02-05 01:00 1007 浏览

Django视图指向一个函数,如果您只想更改一些功能,这可能是一个问题。是的,我可以有百万个关键字参数,甚至更多的if语句,但是我正在考虑更多的面向对象的方法。 例如,我有一个显示用户的页面。这个页面与显示一个组的页面非常相似,但是与使用另一个数据模型不太相似。集团也有成员等... 一种方法是将视图指向类方法,然后扩展该类。有没有人尝试过这种方法或有任何其他的想法?

已邀请:

funde

赞同来自:

听起来像你试图把不应该结合的东西结合起来。如果你需要在你的视图中进行不同的处理,取决于你想要看的用户还是组对象,那么你应该使用两种不同的视图函数。 另一方面可以有你想从你的object_detail类型视图中提取的常见成语...也许你可以使用装饰或只是帮助函数? -担

yquo

赞同来自:

如果您只是显示模型的数据,为什么不使用Django Generic Views?它们旨在让您轻松地从模型中显示数据,而无需编写自己的视图,也不需要将URL参数映射到视图,获取数据,处理边缘情况,渲染输出等等。

uut

赞同来自:

除非你想做一些有点复杂的事情,否则使用通用视图是一种方法。他们比他们的名字意味着更强大,如果你只是显示模型数据通用的意见将完成这项工作。

paut

赞同来自:

如果你想分享页面之间的通用功能,我建议你看看自定义标签。他们相当easy to create,非常强大。 另外还有templates can extend from other templates。这使您可以拥有一个基本模板来设置页面的布局,并在填充空白的其他模板之间共享。您可以将模板嵌套到任何深度;允许您在一个地方的不同组别上指定布局。

inisi

赞同来自:

您始终可以创建一个类,重写 call 函数,然后将该URL文件指向该类的一个实例。你可以看看FormWizard类,看看这是怎么完成的。

liste

赞同来自:

我创建并使用了自己的通用视图类,定义了 call ,以便可以调用该类的一个实例。我很喜欢;虽然Django的泛型视图允许通过关键字参数进行一些定制,但是OO泛型视图(如果它们的行为被拆分成多个单独的方法)可以通过子类化进行更细粒度的定制,这使我可以少得多地重复自己。 (我厌倦了重写相同的创建/更新视图逻辑,我需要调整Django的通用视图不允许的东西)。 我已经在djangosnippets.org上发布了一些代码。 我看到唯一真正的缺点是内部方法调用的泛滥,这可能会影响性能。我不认为这是一个很大的问题。 Python代码执行很少会成为Web应用程序中的性能瓶颈。 更新:Django自己的generic views现在是基于类的。 更新:FWIW,因为这个答案是写的,所以我改变了对基于类的观点的看法。在一些项目上广泛使用它们之后,我觉得它们往往会导致编写代码的代码干干净净,但以后很难阅读和维护,因为功能遍布在许多不同的地方,而且子类是如此依赖的在超类和mixin的每个实现细节上。我现在觉得TemplateResponse和视图装饰器是分解视图代码的更好的答案。

jvitae

赞同来自:

泛型视图通常是要走的路,但是最终你可以自由地处理URL。 FormWizard以基于类的方式执行某些操作,例如用于RESTful API的某些应用程序。 基本上用一个URL给你一些变量,并提供一个可调用的地方,你提供的调用完全取决于你 - 标准的方法是提供一个函数 - 但是最终Django对你所做的没有任何限制。 我同意,如何做到这一点的更多的例子是好的,FormWizard可能是开始的地方。

nin

赞同来自:

我需要使用基于类的视图,但我希望能够在我的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实例尝试实例化一个视图类是无稽之谈。
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/上发布了一个片段)

ysunt

赞同来自:

你可以使用Django的泛型视图。您可以通过Django的通用视图轻松实现所需的功能