我第一次使用Django(我也是Python的新手),而且我一直在努力解决与基于类的视图相关的某个问题。我来自PHP和Laravel,你可以在那里拥有所谓的#34; RESTful资源控制器"。
对于不熟悉Laravel的每个人:我们的想法是,每个资源都有一个控制器(或Django-speak视图)。此控制器/视图定义了诸如index()
,show()
,create()
,store()
,edit()
等方法。这些控制器方法的关联URL和HTTP方法分别是GET /photos
,GET /photos/1
,GET /photos/create
,POST /photos
,GET /photos/1/edit
(例如,如果您正在处理照片)。在Laravel的路由中,您只需要声明一行Route::resource('photos', 'PhotoController')
,并自动生成这些URL。有关详细信息,请参阅Laravel's docs。
我非常喜欢这种模式,我想在Django中使用它。
据我了解,Django并不是真的有这样的东西开箱即用。 Django确实有基于类的视图,但那些不代表资源。相反,您可以查看您的索引()' (PhotoListView
),您的' show()' (PhotoDetailView
)等等。
我不确定如何在Django中实现这种模式,我甚至不确定我想要的是一个好主意。
经过研究,我发现了一些可能有用的信息:
http://watchitlater.com/blog/2010/02/django-restful-resources/
https://baxeico.wordpress.com/2014/06/25/put-and-delete-http-requests-with-django-and-jquery/
我不确定第一个链接中的自定义View类是否完成了Django View的库存(正常的Django View或多或少都做同样的事情,对吧?),我不知道#39;认为第二个链接完全符合我的要求(如果我理解正确,那么这篇文章只是将一个中间件描述为一个解决方案,解决了Django没有在请求中使用DELETE / PUT请求发送数据的问题)。
基于此,我设计了两个可能的解决方案:
在URLconf中使用一行匹配特定资源的所有网址,如下所示:
url(r'^photos/(.*)$', PhotoView.as_view())
然后,自定义View基类的as_view()
函数会处理诸如/photos
,/photos/1
和/photos/1/edit
等网址的路由,以及正确的类方法。缺点是您将路由放在视图中(不是正确的位置)并且您不能以这种方式使用命名模式来引用代码中其他位置的URL。它最接近它在Laravel中的工作方式。
在URLconf中为每个URL使用单独的行,例如:
url(r'^photos$', PhotoView.index)
url(r'^photos/(\d+)$', PhotoView.show)
url(r'^photos/(\d+)/edit$', PhotoView.edit)
这样做的好处是命名模式可以正常工作,并且所有路由都保留在URLconf中。但是,我不知道如何在View类的实现方面做到这一点(我必须装饰每个方法@classonlymethod,对吧)。
对于文字墙感到抱歉,我很高兴听到您对如何最好地解决这个问题的想法。或者也许我只是疯了,我应该像每个普通的Django编码器一样使用基于函数的视图吗?
答案 0 :(得分:1)
正如Jens在评论中所建议的那样。第三方Django Rest Framework是我们对你所描述的laravel控制器最接近的事情。要查看的具体项目是viewsets。
Django REST框架允许您组合一组逻辑 单个类中的相关视图,称为ViewSet。在其他框架中 你也可以在概念上找到类似的东西 比如'资源'或'控制器'。
DRF学习曲线非常陡峭。 DRF还传达了它仅适用于创建API的印象。但是,实际情况是DRF可以用于render HTML and process ordinary HTML forms。
REST框架适用于返回两种API样式响应,以及 常规HTML页面。此外,序列化程序可用作HTML表单 并在模板中呈现。
另一种选择当然是使用基于类的视图。缺点是它不能在单个类中提供DRF视图集的所有功能。但一切都不会丢失。您可以使用CBV Mixins来混合和匹配您需要的功能。
答案 1 :(得分:0)
我最终编写了一个基于自定义类的视图,该视图或多或少是该问题中两个提议的解决方案的混合。
一般的想法是我有ResourceView
遵循与Django的View
类相同的结构(它有as_view()
和dispatch()
方法)。就像Django的View
一样,as_view()
定义了一个返回到URLconf的闭包。此闭包依赖于dispatch()
将请求分派给正确的(子)方法。为此,它使用'2d map'(dicts的dict)来确定应该为route(URL)和HTTP方法的哪个组合调用哪个方法。与Django View
的不同之处在于,在URLconf中调用as_view()
并使用指定路由的参数。
我还有ResourceRouter
自动生成与视图对应的URLconf。这种方法在某种程度上受到了DRF处理这种方法的启发。
最后但并非最不重要的是,我写了一个装饰器,将模型实例“绑定”到方法中,因此模型实例不是传递给视图方法,而是传递给视图方法。
可以在此处找到代码:https://gist.github.com/Compizfox/c4e3044755417f59dc33ce97ac8ca07c