用 Django 写 web 写的无比痛苦,是我的问题吗?

2020-09-21 22:38:07 +08:00
 subpo
最近从 Ruby on Rails 切换到 Python on Django 。才上手写了几天,可能对 Django 理解不深刻,但是这几天真的把我恶心的想吐,这是我的问题吗?还是继续写下去就能发现这个将近 20 年的框架的优秀点?

Python 虽然对我来说还有一点点小别扭的地方(比如明明是一切皆对象,却使用 len(obj)而不是 obj.len()),总体来说写起来还是比较爽,语法比较简单,调试工具链完善,网上能找到的资料也多。

但是 Django 简直让我痛苦无比。

按照官方文档,router 层无法定义请求类型,要在 ViewController 里面写 if request.method == "POST" 。
畸形的模板系统,无法在模板层写脚本,这点我可以理解是架构的设计考虑到不想在模板层引入逻辑,但放着 python 这么有表现力的语言不用,硬是发明了一个新的模板语法,实在是理解不能。

细节的问题更加数不胜数
比如写一些复杂的 View,需要把同一个资源的 POST 和 GET 方法拆开写
post /api/resources create_resource_view
get /api/resources list_resource_view
居然发现 Django 的 router 不支持把这种约定俗成的 RESTful api 导向不同的文件

模板层也各种难受,API 接受到 string 格式的 date 参数,需要转成 date 格式存入数据库,这么一个任何一个 APP 都会遇到无数次的逻辑,都需要 hard coding 或三行以上的代码来处理

API 参数验证也很糟糕,ORM 也很糟糕,一吐槽都停不下来,哪里哪里都很糟糕
4413 次点击
所在节点    问与答
30 条回复
wander639
2020-09-21 22:43:26 +08:00
view 的话可以考虑下 cbv
模板的话不知道能不能自己换成 mako
个人觉得 django 的 orm 还是挺好用的
Rxianbei
2020-09-21 22:46:35 +08:00
啊,对呀,要在 view 层定义请求方式实在是把我看得一愣一愣,这也太不优雅了。
cyssxt
2020-09-21 22:56:33 +08:00
熟能生巧
youngce
2020-09-21 23:00:06 +08:00
1. obj.__len__()是 len(obj)面向对象的写法,不主动定义为 obj.len ()是考虑到很多人也需要对这种东西自定义
2.django 是你的理解还不够的,你列举的那些问题,django 都有完善的高级的处理办法,但是你如果只看了了一个入门教程,可能是还没接触到这些。django 属于那种需要一段时间上手的框架,不要指望一上手就掌握所有 django 特性,如果没有耐心,请使用 flask 。
youngce
2020-09-21 23:02:06 +08:00
CVB 是不要整这些 view 层定义的,路由也是完全的 rest 风格,正经写 api,也都用 drf 的,不要被一些水货教程误导了
subpo
2020-09-21 23:09:32 +08:00
@youngce #5 rest framework 有在用,我也想吐槽来着,serializer 就我个人的感觉,一般是格式化输出的东西,但是 rest framework 把 serializer 同时作用于参数输入,验证,存储和格式化输出,一些常用的功能(自定义输入验证,输出附上一些自定义字段)也没能简单的提供,都需要进行一些有些奇怪的操作。

不过有你这么说我就放心多了...较长时间里不得不接触 Django 的话,宁愿是我自己菜
Philippa
2020-09-21 23:17:06 +08:00
Django 起手挺复杂的,而且设计得很繁杂,很多魔法,我一开始也很难适应。我后来找到一个入门 tutorial 去写个小 demo 才慢慢入门。

一般使用 rest_framework + Django + 一点最佳实践。用 ModelView 和 Model Serializer 那种高度抽象得语法来写,开发速度非常非常快的,而且它生态很好,除了基础功能,连 aws 等平台绑定的 libaries 也一大堆,如果你想最大化自己的开发速度,Django 一定是 Python 最好的选择,即使和其他语言的 Web 比较如 PHP 和 Ruby 也毫不逊色。

我用 Django 写 web 大部分时间其实都是遵照 TDD 写 unittest 的,因为一般常见的 API 开发,写 view/model/serializer 等都没多少行代码,大部分代码都是 unittest 。但这种高度抽象的写法很容易出错,多一行,少一个方法可能相差非常大,不写 unittest 来 debug 是非常困难的。

建议多花一周实践继续研究一下,我当时刚开始也觉得很痛苦= =,怎么设计那么脏,为什么要用字符串而不是类,为什么要去 override 那么多方法来实现 api 等等,中途还一度放弃去写 flask/echo,但最终尝试下来发现这值得,开发效率非常非常高,现在我个人开发都是 Django + React 。个人的 Nodejs 的 Nestjs 还是 Expressjs 的开发效率和 Django 还是差一个等级。
subpo
2020-09-21 23:19:53 +08:00
@subpo #6 我表达的不是很清楚。重新说一下

比方说一个 api 的 create 部分的常见操作:
1. 验证传输进来的数据的合法性,包括数据格式转换,验证等
2. 进行一些业务逻辑后存入数据库
3. 返回存入的字段和一些自定义字段

这个常见的操作用 drf 怎么都走不顺。操作 1 的 serializer,操作 2 的 model,操作 3 的返回 serializer 几乎是同一样东西,但是又有一些细节不同,实现起来很别扭,不顺。

并且个人认为 djr 的 Restful 设计的不太好,诚然做一个标准的 CURD 操作用 Viewset 非常方便用不了几行代码,但是真正放到业务逻辑里,又有多少标准又无扩展逻辑的 CURD 呢?这时,djr 需要用不同于 Viewset 的另外一套逻辑来处理这部分业务逻辑,显得非常脆弱。
iConnect
2020-09-21 23:27:59 +08:00
如果熟悉工厂模式,换 flask 吧,django 的路由设计不如 flask 来的简洁。
dcalsky
2020-09-22 00:11:38 +08:00
@subpo DRF 就是开发小功能快,你要做细的话,那就得好好看看各个 serializer 以及 serializer relation 。很多逻辑要在 serialization 的 create validate save 里面做。
comwrg
2020-09-22 00:19:23 +08:00
同样的感觉…
comwrg
2020-09-22 00:22:09 +08:00
要不是 python 轮子多,对于个人开发者来说我还是选择 rails,而不是 python 的 web 框架
oahebky
2020-09-22 01:00:58 +08:00
是你的问题。
zachlhb
2020-09-22 01:14:56 +08:00
cbv 是可以定义请求类型,class 里方法名定义成 method 就行了
zachlhb
2020-09-22 01:18:02 +08:00
如果写接口可以用 drf 的 viewset,然后在路由的 as_view 里面定义请求的 method 和对应的方法
MintZX
2020-09-22 01:38:47 +08:00
ruby on rails 开发给你点个赞。。。

确实不喜欢 django 的写法,但是新公司的技术栈就是 django 和 flask,只能被迫用了
ericls
2020-09-22 02:19:07 +08:00
不就是个 wsgi
steptodream
2020-09-22 07:36:15 +08:00
我是二流搞 IT 的 被迫开发内部 web 适应尝试了一圈 发现对于我来说 django 最容理解
wellsc
2020-09-22 08:18:49 +08:00
用 go 试试(手动狗头
0312birdzhang
2020-09-22 08:32:05 +08:00
+10086 啊,写的太痛苦了,于是我用 java 了(滑稽

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/709193

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX