一次采用DJANGO开发应用的悲剧

2012-09-01 17:02:18 +08:00
 zyyzj
典型的把“锤子当成榔头“的案例。决定这个过程记录下来,希望给同行”如何更正确的使用DJANGO"带来一些参考价值。如果使用“AAA如何用BBB来实现,遇到CCC问题”这个记述体,显得太干巴巴太无趣,因此我使用“自传小说体”的手法来记述,其中更夹加了自己的行业经验的一些私货在里面。


## 背景:
我:十多年的程序开发,从事过的领域跨度非常大,正处于再次创业阶段;

死党(除了女人外什么都可以共享的好友):风电行业设备提供商,天生的销售,自称为:技术员中最懂业务,业务员中最懂技术,最熟练的软件技能是QQ,TAOBAO。1年前因功高震主被原老板排挤出门,忿而自定门户,经1年折腾,頗有成就,业务隐然赶超原公司。

我们一起租了一层楼,除了各自工作和晚上各回各家外,平是都是泡在一起。


## 缘起

事情缘起于二周前的某天。

晚上7点多,死党突然跑过来问了一堆关于EXCEL的高级使用技术,甚至包括宏如何定义和使用的问题,记得当时我正专心写产品规划,虽然奇怪得要命,也就随口应付几句了事。

晚上10点多,回家前去他办公室溜达时,发现其正在与一堆EXCEL表以及N个EXCE汇总小软件较劲。这种诡异的现象我当然不能放过,立马凑了上去:“你在干什么呢?”

接下来,我在听了20分钟他想要通过EXCEL实现的一些古怪的功能后,总结了一句:你不就是需要一个销售汇总系统嘛。

“对对对,就是销售汇总系统“,听到这个名词,死党黝黑的脸膛兴奋得发出了红光,如同喝高了一般。

”这事你不行,我来“。我拍拍他的肩头,示意他从老板椅中起身。

展现在我的是一个手工管理的销售系统:3-5层的目录结构,平均每层有7-10多个下级目录,分布其中,加起来约有数以百计的EXCEL文件。

死党站在我背后,估计是一脸牛B地描述着他所建立的EXCEL模板有多么多么完善,我的内心,却是为他当年没有好好去上数据库基础课程悲哀不已。因为我需要在N个不同层次的目录来回切换打开N几个不同的表,组合在一起,才能理解他描述的业务流程。

等我咬牙切齿地把关键表的字段和内容都过了一遍后(其间充斥着我对他设计表结构能力的吐嘈),已是接近晚上12点。

”交给我吧,明天我帮你搞定“。

听到这句话,死党那原本被我的吐嘈打击得黯淡的脸瞬间再次发出了红光。手舞足蹈地出了门,手舞足蹈地进了电梯,手舞足蹈地坐进了大奔的驾驶位。更大的房子,更好的车子,更多的妹子,仿佛一切即将实现。以至于一路上,我不断提醒他注意前方,不要总侧着头对着我描述他伟大的商业计划。
20030 次点击
所在节点    Django
75 条回复
paloalto
2012-09-04 18:08:29 +08:00
我记得原先的v2ex是有只看楼主功能的啊。
zyyzj
2012-09-04 19:36:04 +08:00
ADMIN的权限结构基于表模式,要么可以访问,要么不能访问。我很怀疑这种权限设计能有多少场合可以不加修改地直接使用.
ADMIN在FormAdmin类中使用了三个函数:has_add_permission, has_change_permission, has_delete_permission,来实现基于表记录的权限控制,所以,只能为每个表生成一个FormAdmin类,在每个类的上述三个函数中进行用户身份判断,一堆的IF语句,想抽象都抽不出来。

2. 系统行为

这点与权限的结构设计息息相关。

ADMIN的记录等级的权限只有:增加,删除,修改。很常见的一种行为:一个用户只能浏览不能修改另一个用户的记录,必须要配合get_readonly_files函数才能实现。于是,理论是只是一次“只读“的权限设定,被分成二次实现:要先为此用户设定”允许修改“,然后在get_readonly_fields中返回所有字段,才能实现“只读”页面,于是不得不在所有FormAdmin类中的get_readonly_fields中,把与has_add_permission等几乎相同的用户身份识别的过程,再来一遍。还是想抽象都抽不出来。

更要命的是,记录的修改页面的下方是带有“删除”按钮的,这不是一个简单的前端显示问题,而是涉及到“系统行为”,ADMIN的所有页面是通过一套如同精密生产线一般的流程生成的,ADMIN也提供众多的选项和函数允许你改变一些行为,但是很不幸,这些可定制部分并不包括“修改页面中的删除按钮”。

怀具直接变成了餐具。

我用了一天的时间,阅读源码中相关部分,理解整个流程,所有参数的作用,才能在上一层的上一层,在Request类中增加标识,再一层一层向下传递,最终在模板中读取标识,来决定是否显示删除按钮。
这就是“在一个页面上去除删除按钮”的这种表面看起来简单得不能再简单的问题的解决代价。

类似的情况,在接下去的几天中不断地上演,ADMIN的源代码也被我翻来覆去的看了好几遍。

这些情况包括:
* 显示列表页面中实现外键字段的超链接
通过list_display和函数的allow_tags实现自定义字段,这个结构很精巧是没用,但是函数调用花费很大的啊,记录数乘以字段数,得用多少次调用啊!!!!!如果需要执行复杂一点的用户权限判断,必然用到外联表查询。这开销,想想我的汗毛都能竖起来。
* 基于权限的过滤列表
* 父子从表的显示风格
* 登录时的首页面更改
等等等等。

只要是在ADMIN现有的选项之外的功能实现,都得过一遍源码,才能知道如何在紧密结合的齿轮中加入自己的一环。

在解决这些问题的时候,时间一天天过去了。

死党经常过来看一眼系统的进展,虽然没有说什么,但我几乎听得到他的内心独白:你当时说是[就4个表的录入,权限部分复杂一些的简单系统],搞了这么多天,行不行啊,还AABB行业专家,还号称要开发多牛B多历害的网络金融交易平台呢,吹牛B吧你。

男人最郁闷的是什么时候?
就是被死党怀疑行不行的时候。

从建立Model类那天算成,当最后一个需求(基于关键字的表搜索自动下拉框提示,如同GOOGLE的输入框一样)完成的时候,已是第九天。离我当时说的”三天完成“足足多了三倍时间。这其中,至少有一半的时间,是用在了”理解ADMIN“上面。

我TMD当时为什么要选择“基于ADMIN修改”啊!!!!!!!!!!
如果只是基于DJANGO,手工实现整个系统,早TMD完成了,还差点毁了自己的形象。

最终,一个有着漂亮界面,完全符合需要的销售系统,被交给了死党。我惬意地躺在午睡椅上,死党在旁边兴高采烈地录入着测试数据,随着系统一一展现符合预期的功能,不时地发出:对,就是这样!得了!。

“刚刚我想到许多非常重要的新功能", 死党转过身来,死盯着我,红光又隐隐在出现他黝黑的脸上,各种新奇的想法随即喷涌而出。

“绝不要试图通过软件解决管理问题”。我闭上眼睛,一语定论。
当年的ERP实施浪潮中,多少企业试身,多少资金投入,称的上成功的,曲指可数。论其根本,或多或少都是没想明白上述这点。

“你后天要去西安?多大的标啊?“,我突然想起某件事,侧过头,问死党。
”是啊,大概100万吧,没什么问题。到时正好用得上这系统,把项目进度管理起来。“,死党的声调充满自信。这点我绝不怀疑,这家伙天生就是干销售的。
”那么庆祝一下系统完成兼项目到手,叫上XXXX一起,我现在打电话给Nobu预订个位置?",我眨了眨眼。
"那个太贵了吧!!!1000万的项目到手才能去!!!!“,死党仿佛挨了一刀般地叫嚷起来。
”也是,那就松梅亭吧,也别选最贵的那档,200一位那个不错”,我再次眨吧了几下眼睛,说出了真正的本意。
“这个行。但,为什么要吃日本料理,你不知道现在小日本又在钓鱼岛闹事了吗?这种民族就该xxxxxxx“,死党的民族魂瞬间爆发。
"你懂个P,要打到敌人,就得先了解敌人,明白吗?“
”对对,女的留下,男的全杀光“。

好基友总是一拍即合。

如果我一开始就提议去松梅亭选200元一位的档次,死党一定会爆了菊般嚷嚷,从而最终会选择100元的那档。
客户也是如此,你先一步抛出远远超过其心理承受能力的资源要求,那接下来其提出来的需求往往会合理很多。面对客户的需求,绝不要直接回答不行,通过资源要求来迫使客户自己降低期望。

这就是我得到的很重要的项目实施经验。

故事完结。


总结开始:

1. 我吐嘈的是DJANGO的ADMIN,不是DJANGO。
2. ADMIN是一个非常完整的DJANGO应用,学习DJANGO的不二之选。
3. 看看文件数就知道,ADMIN的开发占据了不少开发资源。
4. 即然是重要的功能,干嘛把ADMIN搞成“只能是在开发阶段给程序员或测试员使用的东西啊“???
5. ADMIN完全可以做成"基于DJANGO的更快速方便的框架生成系统“,现在的代码已经很接近了啊!!!!只要把权限系统和ChangeList类相关抽象出来。
6. 干嘛要把最重要的ChangeList类,搞得就像动一动就会爆菊似的,层层叠叠保护那么严密????????
7. 为什么要把Users的物理表结构也给设定了啊啊啊啊?世界上能有几个真实项目的用户信息表结构是一致的啊!名义上的用户表一堆没用的字段,强迫要搞一个表关联起来,才能保存真正需要的用户信息,这TMD的多诡异啊!一开始就把Users抽象成一个类,不就完了吗?


教训:DJANGO的ADMIN是给开发员使用的一个工具,绝不要试图对其定制以快速完成一个业务系统。
zyyzj
2012-09-04 19:39:31 +08:00
@hzlzh dash很不错,但不适合查询页面跳转很频繁的内容。
hzlzh
2012-09-04 20:55:40 +08:00
@zyyzj 今天两更了啊,不错。
dash打开 stackoverflow 后前进后退的确有点弱,等更新新的按钮吧。
PrideChung
2012-09-06 00:06:19 +08:00
啊?这就完了?说好的悲剧呢?说好的兄弟反目妻离子散家破人亡自挂东南枝呢?
xiaket
2012-09-06 16:48:15 +08:00
django的admin真的只能是给管理员用用, 要功能扩展肯定还是自己写视图函数靠谱. 之前也是在这个上面花了好多无谓的精力.

顺口吐槽, 而django的form就根本不是人用的...
yaotian
2012-09-06 17:41:13 +08:00
真欢乐
ileto
2012-09-07 22:20:35 +08:00
还好吧?
yishanhe
2012-09-07 23:53:02 +08:00
看完了.. 我在v2ex不在豆瓣吧?? 求继续
cloudzen
2012-09-08 09:58:46 +08:00
强帖留名
oth
2012-09-08 22:05:33 +08:00
不学软件工程害死人哦
superisaac
2012-09-08 23:12:28 +08:00
记得原来在某外企也是定制django搞出个销售管理系统的,还是著名的0.96版,呵呵,那个烦人啊。
hepochen
2012-09-15 03:17:33 +08:00
@zyyzj
7. 为什么要把Users的物理表结构也给设定了啊啊啊啊?

凌晨太晚,没有全看完,但光这一条就是不成立的,django+python,合起来,对contrib.auth.models.User本来就有很native的扩展方式。

甚至,我认为你都理解错了(User)Profile的意义,它从词义上就不是UserExtends。实现方式虽然都是表关联,但绝对不是设计的初衷。

哥,这个点,决然是吐错了的。
imcj
2012-09-15 22:53:24 +08:00
这个没有人定义这里不能连载小说吧。
husw
2014-03-22 22:59:46 +08:00
曾经的0.96版...

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

https://tanronggui.xyz/t/46657

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

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

© 2021 V2EX