一次采用DJANGO开发应用的悲剧 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
zyyzj
V2EX    Django

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

  •  
  •   zyyzj 2012-09-01 17:02:18 +08:00 20532 次点击
    这是一个创建于 4789 天前的主题,其中的信息可能已经有所发展或是发改变。
    典型的把“锤子当成榔头“的案例。决定这个过程记录下来,希望给同行”如何更正确的使用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点。

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

    听到这句话,死党那原本被我的吐嘈打击得黯淡的脸瞬间再次发出了红光。手舞足蹈地出了门,手舞足蹈地进了电梯,手舞足蹈地坐进了大奔的驾驶位。更大的房子,更好的车子,更多的妹子,仿佛一切即将实现。以至于一路上,我不断提醒他注意前方,不要总侧着头对着我描述他伟大的商业计划。
    75 条回复    1970-01-01 08:00:00 +08:00
    iiduce
        1
    iiduce  
       2012-09-01 17:10:38 +08:00
    这是要写小说吗,怎么没看到django什么事?
    PrideChung
        2
    PrideChung  
       2012-09-01 17:14:17 +08:00
    估计是要写个小长篇了,但愿不要太监。
    fen
        3
    fen  
       2012-09-01 17:17:28 +08:00
    占座,等楼主更新。目前没发现 django 的影子
    zxy
        4
    zxy  
       2012-09-01 17:21:49 +08:00
    bhuztez
        5
    bhuztez  
       2012-09-01 17:29:38 +08:00
    目测LZ使用了QBE

    http://versae.github.com/qbe/
    DaniloSam
        6
    DaniloSam  
       2012-09-01 17:49:58 +08:00
    占座
    paloalto
        7
    paloalto  
       2012-09-01 17:52:24 +08:00
    希望不是坑
    sin2624
        8
    sin2624  
       2012-09-01 17:54:08 +08:00
    求榔头和锤子的异同…
    pinkman
        9
    pinkman  
       2012-09-01 17:55:53 +08:00
    占座
    elvba
        10
    elvba  
       2012-09-01 18:13:49 +08:00
    不能太监啊楼主
    neodreamer
        11
    neodreamer  
       2012-09-01 18:56:12 +08:00
    楼主挖了个大坑,你要负责埋完啊,不能祸害路人。
    zyyzj
        12
    zyyzj  
    OP
       2012-09-01 19:38:22 +08:00
    @iiduce 不要着急,铺垫嘛,现实中重要的技术决策,也总是经过几近波折才定的下。
    iiduce
        13
    iiduce  
       2012-09-01 19:41:16 +08:00
    @zyyzj 我最近的几个项目都是基于django,所有很感兴趣。
    zyyzj
        14
    zyyzj  
    OP
       2012-09-01 19:44:22 +08:00
    # 第二天

    昨晚我是心里有底才会说出那句话的。

    尽管有上百个EXCEL,但各种字段分类整理后,真正有用的,也就是四张表:项目表、客户表、联系人表、项目跟进表。通过“销售人员”这个关键字段把表之间关联起来。

    “不就是最典型的企业应用的数据结构嘛,老子18岁就在处理这些类型的应用了"。当然了,就是再哥们,也不能这么直接打击人,因此,这话只有在心里嘀咕嘀咕。

    三下五除二,整理出一个清楚的表结构。

    接下来,就是选择适合的开发工具。

    如果没有”长期出差在外的销售员需要通过网络访问“这个需求的话,我一定会选择VirtualFoxPro,这货天生就是处理这类企业应用的工具,但也天生就是处理单机应用的命。

    FoxPro,每提到这个名词,就有一种千言万语却无从所说的感觉。仿佛那个名词与我过去的年少轻狂的青春重合了一般,太多记忆。

    你见过为了竞争把当时市场第一的优秀软件花了大价钱买下却又故意抽走资源从而为自家二流的软件让道的企业吗?对了,就是微软。

    你见过十五年几乎没有更新,却至今仍有一群不愿意彻底放弃使用的软件吗?对了,就是VisualFoxPro。

    哈,不小心扯远了。回神,回神。

    接着,我选择了FileMaker。尽可能使用现有成熟的工具解决现有问题,不存在时才选择自己开发,这是我的原则。(再次怨念,为什么当年不是苹果,而是微软买下了FoxPro。要是FoxPro正常地发展下去,特别是在2.6版本后,那FileMaker根本不会有出现的可能。)

    下午约2点时分,我把整理好的样表和一份中文版的FileMaker试用版交给了死党:“既然你肯花时间研究EXCEL,那一定也可以花点时间研究下这个软件怎么用,况且这个软件可以完整实现你的意图”。死党一如即往的乐观:"没问题,当年我也是技术人员"。

    我当然没指望死党自称的技术能帮助他建出想要的销售系统来,当时我的如意算盘是,毕竟许多业务操作流程只有他自己明白,一些细节他自己也没有完全清楚,通过自己动手,可以理清思路,最后把一个能体现架构结构的原型交给我,我再过优化调整为可使用的产品,通过Server版的FileMaker发布到公司内的某台电脑上。外网用户通过在路由器映射访问此内网服务器。

    这样一来,我不要花时间去深入了解业务流程,死党能体现他的技术创造欲,更不需要额外的机房或服务器等开支。一切似乎都非常美好。

    可,事情会向我设想的美好方向进展吗?

    当然不会,否则就没这篇文了。
    zyyzj
        15
    zyyzj  
    OP
       2012-09-01 19:45:42 +08:00
    @sin2624 分别用锤子和榔头敲一次钉子,就知道区别了。
    neodreamer
        16
    neodreamer  
       2012-09-01 21:02:48 +08:00
    FoxPro 有同感。
    zyyzj
        17
    zyyzj  
    OP
       2012-09-01 23:27:59 +08:00
    # 第四天

    隔了一天,我的文档暂时告一段落,该去看看死党的那燃烧的技术魂发挥到了什么地步。

    约中午11点30分左右,我推门进入他的办公室。死党的27寸的显示器过于巨大,只能呈45度侧放在左手边上。一接触到他回过头来那神情呆滞的目光,我立刻意识到了:不管是我还是他自己,都过高的期望了其内在的技术魂。

    死党,看着我,叭眨了几下眼睛,定了定思绪,喉结动了几下,正要开口发挥,我赶紧制止:好啦好啦,我知道了。先吃饭去,接下来你什么就别管交给我就行了。

    一份上好的牛排,一杯鲜酿啤酒,足以安慰他受到挫折的心灵。

    话题一回到他的业务,加上美食的作用,死党立刻如同打了鸡血般兴奋起来,而这次,我必须认真的听取他讲述的每一句话,如同面对真正的客户,不,现在他就是我的客户,我也立刻调整了自己的心态。

    这顿饭一直吃到快下午2点才结束,我也得到了足够的业务信息。

    一回到办公室,马上打开FileMaker的特性文档,逐条阅读重要的功能。FileMaker就是给不具备专业计算机知识的企业管理人员使用的,一定提供了许多方便的企业应用功能。我需要以最少的工作量完成这个系统,这很大程度上信赖于我能使用直接哪些系统功能。

    权限分配,界面设计,数据结构,脚本语言等都没有问题,我想要的东西看上去FileMaker都提供了,直到“服务端发布和产品报价”。

    一看到那一堆的对系统操作系统和环境的要求,瞬间勾起了早年为企业部署WindowsNT网络应用的黑暗记忆。而那个服务端,客户端授权数等加起来的产品报价,已经足够支持死党一脚把我踢出几十层楼上的窗户。

    "看来,只能自己开发整个系统了”。

    我叹了口气。

    在我所有的专业技能中,与互联网Web应用(企业网Web应用往往有很大不同)有关的,只有Python和PHP。PHP一般是在无法使用Python的环境下才使用。而我的所有Python技能中,与Web框架有关的,也就是Django了。虽然那个经验来自于那是很早之前,还是0.96版本的时候,做过的一个简单查询系统。

    所以,很自然的,我选了Django。

    真想看看现在的新版本又有什么新特性啊!

    新的软件,强力的特性,总是能带给我难已形容的激动,如同每每有新的妹子出现给死党带来的激动一般。

    在空白CD还是2倍速刻录,几十元一张的年代,我就通过0DAY下载收集了整整一CD包各种各样的软件。其中绝大多数软件我都安装过,使用过,根据使用感觉决定保留在硬盘上时间长短。特别是与编程相关的软件,更是乐此不疲。每天必做的一件事是,晚上浏览0DAY站点,下载当天发布的感兴趣的新软件。

    到后来,发展出了这样的技能:绝大多数的桌面应用软件,扫一眼界面就可判断出是什么语言写的,八九不离十。这在当时很重要,因为每种编程语言或工具,生成可执行码都带着自身的特征,想要破解某个软件,搞清楚是什么语言写的,非常重要。不要问我为什么会“想要破解某个软件”,我什么都不知道。

    0DAY,又是一个难忘的名词,更是一个曾经的传奇。

    知道为什么叫0DAY吗?就是号称:世界上任何软件都在能发布的当天被破解:Zero Day。你知道当年0DAY有多牛B吗?据传当时要去微软,INTEL等公司应聘,只要声明你是0DAY成员,就能得到特别对待。我无法证实,但我相信。因为,那些公司那时本质上都是程序员为核心,0DAY成员则是证明你是个牛B程序员的最好标签。

    全世界都有0DAY组织分部,不同分部的专攻不同,分别擅长破解不同类型的软件。各个小组抢着发布最热门软件的第一个破解版本。只为证明你比别人牛B,只为热爱计算机。那时,0DAY就是我们的圣地。至于中国,呃,不提也罢。

    再后来,商业利益渗入后,一切都变了。过于危险的力量被导往不正确的方向后,终于迎来了恶果:那次全球各国联合大清除。从根本上瓦解了整个0DAY,因为没有人愿意被打上罪犯的标签。

    再后来,呃,打住打住,又远了,回神,回神。

    咦??刚才我说什么了吗??我什么都不知道。

    回到DJANGO。

    尽管我事实上对DJANGO的了解没多少,又是来自很久之前的版本。但,凭着自身的PYTHON及综合经验,我有足够的自信对死党说:三到五天,给你一个可测试的版本。

    男人最得意最有成就感的是什么时候?

    就是身边的另一个自认为也是很强的男人能把身家性命相关的难题交给你,相信你一定能解决的时候。

    用DJANGO,是错误的选择吗?

    不,绝对是正确的,如果不是接下去的我的另一个选择的话。
    daweiba
        18
    daweiba  
       2012-09-02 00:12:31 +08:00
    赶上直播了
    CoX
        19
    CoX  
       2012-09-02 00:23:03 +08:00
    好了,Django出场了
    kojp
        20
    kojp  
       2012-09-02 04:12:26 +08:00
    好吧,越来越有豆瓣的气氛了。LZ狗昂。
    aisk
        21
    aisk  
       2012-09-02 11:11:23 +08:00
    等下文
    sillyousu
        22
    sillyousu  
       2012-09-02 12:43:39 +08:00
    张哥还不粗现!
    linsk
        23
    linsk  
       2012-09-02 12:55:47 +08:00
    真心需要您这么一位基友。...
    chrisyue
        24
    chrisyue  
       2012-09-02 13:07:04 +08:00
    围观,虽然不是最得意的成就感,但是我也真心希望身边有可以托付身家性命攸关的难题的好基友LOL
    ssword
        25
    ssword  
       2012-09-02 13:41:07 +08:00
    0day的描述有bug
    dianso
        26
    dianso  
       2012-09-02 13:42:25 +08:00
    可以控制在100字左右
    iloveayu
        27
    iloveayu  
       2012-09-02 14:03:32 +08:00
    养肥了看~
    lovebirdegg
        28
    lovebirdegg  
       2012-09-02 14:31:26 +08:00
    应该加上只看楼主的功能
    lgn21st
        29
    lgn21st  
       2012-09-02 14:36:27 +08:00
    写的真好,很有一种现场带入感~
    Fikhtengol
        30
    Fikhtengol  
       2012-09-02 20:10:31 +08:00
    mark
    cydamn
        31
    cydamn  
       2012-09-02 21:48:08 +08:00
    mark 好有趣楼主别太监~~
    xlaok
        32
    xlaok  
       2012-09-02 21:57:49 +08:00
    第三天呢?
    yys
        33
    yys  
       2012-09-02 22:11:55 +08:00
    楼主字里行间聊聊数句就把人带回了那段美好回忆的岁月,turbo c 2, turbo pascal 7, foxbase, foxpro, visual basic 3, delphi 1, borland c++ 4.5 ... ...
    rainchen
        34
    rainchen  
       2012-09-02 23:06:08 +08:00
    文笔不错 很有带入感
    lxkaka
        35
    lxkaka  
       2012-09-02 23:37:54 +08:00
    好带感啊 楼主!
    zyyzj
        36
    zyyzj  
    OP
       2012-09-03 03:29:22 +08:00
    # 第五天

    宽敞的办公室,凉爽的空调,护眼的显示器,顺手的ML系统,舒适的椅子,在“一切都好的环境”中,开始了我最喜欢的工作。心情想不好都难。

    选定的架构为:PYTHON,DJANGO,SQLITE3.

    之喜欢PYTHON,最主要的原因,在于:丰富的数据结构以及灵活不受限制的组合表达方式。现在的新一代程序员和我那个年代过来的程序员,有个很明显的区别:对于数据的理解不同。也许这也是桌面程序与WEB程序的不同。

    “蠢货,要好好思考数据是怎么存储的,所有的计算都是为数据服务的,数据,数据才是重点”。我忘了是哪本书上看的这句话,大意如此,不是原话。

    那时,不管是用C,C++,还是PASCAL,或是其他什么,建立一个符合需求的数据结构都不容易。你需要用最基本的几个数据类型,创造整个世界。指针,数组,内存分配,每个都需要百分之一百的小心谨慎。那天杀的中文字符串,单字节双字节,多少兄弟在这点上被折腾的死去活来。

    对了,在Window 95之前,还必需懂得“显卡图形模式“,从字符模式切换到图形模式,才能画出点像样的界面来。真的是按像素点计算一个线框一个线框画出来的。下拉菜单,那是高级货。你要是能做出那种效果,绝对被帖上牛人的标签。

    PYTHON是至今为止唯一一种能让我感受到“行云流水”般编程快感的语言。

    PYTHON的创造人在介绍PYTHON时有这么一句话:如果它看起来像鸭子,听起来像鸭子,那它就是鸭子。一开始不明白,终于有一天,突然悟通这句话,差点喜极而泣。

    一个没有形成自己的“常用工具集”的程序员是称不上专业的,除了安装外,更是要把它们配置得如同自己的手指一样灵活调用。

    tmux, virtualenv, ipython这三个对于python开发是必备的。

    嗯,环境搭建开始。

    1. virtualenv django
    2. 在.bash_profile中定义别名:py_django="source ~/python/virtualenv/django/bin/activate
    3. py_django
    4. easy_install django
    5. easy_install south

    django环境安装完成。

    接着,是文档部分。

    打开www.djangoproject.com。“哟,都到1.4版本了,上次频繁访问这个网站还是0.96版本呢,时间真的很快”,我一边感叹一边打开最近两个最近版本的release notes,仔细地浏览。

    然后是Documentation页面,查查有没有新出现的条目,再研究了下网站的搜索页面的URL的生成规则。

    “嘿,各种细节增强还真不少,但这次的开发需求很简单,没必要再去深入了解那些新特性,整体架构看起来没什么变化,下午再花点看看Field和URL相关的文档温习一下,就行了“。

    打开alfred的配置界面,增加两条自定义搜索:
    Search URL: http://stackoverflow.com/search?q=[django]+{query}
    key: so_dj

    Search URL: http://docs.djangoproject.com/search/?q={query}&release=6
    key: dj

    在任何时候,只需两步:

    Ctrl+Space,so_dj 搜索关键词
    或者
    Ctrl+Space,dj 搜索关键词

    就能在网上最靠谱的两个有关django的地方(stackoverflow的django区或django的1.4版本的官方文档)搜索问题的答案,在95%的情况下,就算找不到答案,也会给出一些线索。如果连有用的线索都没有,那么就是这问题本身的提出就不正确,需要再一上层重新思考。这是我的经验。

    嗯,文档搜索也配置好了。

    接着,就是编辑器部分。VIM,当然是VIM了。

    1. 下载django-1.4的源码
    2. ctags -R .生成tags
    3. 在vimrc中增加函数:

    function Django()
    set path+=~/program/Django-1.4.1/django/
    map <F3> :CtrlP ~/program/Django-1.4.1/django<CR>
    set tags+=~/Program/Django-1.4.1/django/.tags
    endfunc

    启动MACVIM,输入:Django(),瞬间,完整的DJANGO世界的入口就在前面,
    CTRL+P,CTRL+],CTRL+T,如同庖丁解牛,游刃有余。

    我已经忘了第一次是怎么遇到GVIM,为什么要下载安装,我只记得大概是22岁那一年,有整整一个月时间,每天上班唯一做的事就是阅读VIM文档,研究用法,全然不顾项目进度。

    至于与EMACS的缘分,则记得很清楚,微软的NET平台核心的开发者,就是写<<net本质论>>那个大胡子,在某次技术展示上现场编写示例代码,用的是EMACS,淡黄背景黑色文字,只见大段代码如同有生命的精灵般此起彼落,编辑窗口下面居然带了个SHELL窗口。那时,年少见识短,看得我当场眼睛发了直。视频一结束,就满世界搜那个编辑器。

    VIM是一个能让你体会到“境界”的编辑器:帆随湘转,望衡九面,及输入之极意。

    呃,编辑器是我的又一个敏感点,又扯远了,回神,回神。

    有了框架,有了文档,有了编辑器,最后再来一个git init,齐活了,完整的一个DJANGO开发环境构建完成。

    死党今天不在,带着司机出门,一定又有酒局。

    也好,乐得清静。于是我就在更欢快的心情中度过了下午,完成了4个表的MODELS类。

    git push。美好的一天结束了。

    “嗯,明天让他看看模型,调整一下就可以输入数据了。这速度,会让他吓一下跳的,让他看看啥叫实力“。我把椅子推开半米,向后一靠,双脚放在桌面上,惬意的想着。

    明天,一个令人充满美好和希望的字眼。但,我不知道的是,当时的”明天“却意味着所有的麻烦真正开始。
    elvba
        37
    elvba  
       2012-09-03 03:47:19 +08:00
    LZ是文艺的普通2B青年。
    mani
        38
    mani  
       2012-09-03 09:07:57 +08:00
    等重点
    tokki
        39
    tokki  
       2012-09-03 09:18:21 +08:00
    直播是很无聊的好吧。。。我非常方案这种行为,这里是为了解决问题的 麻烦去豆瓣
    tokki
        40
    tokki  
       2012-09-03 09:18:41 +08:00
    反感这种行为
    imcj
        41
    imcj  
       2012-09-03 09:39:07 +08:00
    提醒 @zyyzj 今天记得码字。
    Danfi
        42
    Danfi  
       2012-09-03 09:42:44 +08:00
    今天有几更呢
    evlos
        43
    evlos  
       2012-09-03 16:06:49 +08:00
    等更新 =w=
    akira
        44
    akira  
       2012-09-03 16:48:15 +08:00
    lz加油,等着更新呢。
    SAGAN
        45
    SAGAN  
       2012-09-03 17:05:00 +08:00
    LZ什么时候更新啊,等着看后面情节呢。。
    clippit
        46
    clippit  
       2012-09-03 19:10:52 +08:00
    居然没有更新了
    hzlzh
        47
    hzlzh  
    PRO
       2012-09-03 19:37:55 +08:00
    @zyyzj 看到你第五天有一个操作的时候(Alfred Search URL: http://stackoverflow.com/search?q=[django]+{query})
    还是推荐一下你Mac下, Dash app自带的这个功能。
    另外,坐等更新。
    rightgenius
        48
    rightgenius  
       2012-09-04 09:34:48 +08:00
    厉!坐等更新!
    catsky
        49
    catsky  
       2012-09-04 12:56:00 +08:00
    给v2ex带来文艺性,不错
    zyyzj
        50
    zyyzj  
    OP
       2012-09-04 13:32:07 +08:00
    # 快进

    注:写这篇文的动力在于一台新的MacBook Air和一款新的应用(ia Writer)的组合,突然让我很想很想写点什么。很久没有感受过这样功能纯的软件,这让我回想起来永远存在记忆中的Borland的蓝底白字的TC 2.0带给我的感觉。
    现在的应用软件往往太复杂,如同现在的生活一样。
    原本我只想吐嘈下DJANGO,谁知双手一放在键盘上,那些过去的记忆争先恐后迫不等待一涌而出,令我自己也愕然不已。在前面几次出现的“打住,回神”,实际上都是写了大段大段的文字,出于一些考虑,发贴时给去除了。
    再这么记下去真要写成小说了,周期一长,太监的可能性就会大大上升。项目开发也是如此,把握进度一定要:快、准、狠,开发周期越长,越不可控。
    必竟这篇文的名称是顶着DJANGO的,所以我决定“快进”。尽量压缩与技术无关的部分,同时保持前几次的文字风格,一次就把这个帖子给结了,再另开新贴记述别的内容。

    我在死党的WIN7上安装好python,django还有cywgin,git pull一下,再写一个简单的bat文件放在桌面上。测试环境布置完成。

    “这么快就完成了??让我看看,让我看看”,死党叫嚷着冲进来。
    ”完成个P啊,许多细节连你自己都没有搞清楚“,我嘀咕了一句,才回应:”只是原型,你看一下各表的字段是否符合要求,有没有漏掉的“。

    一次典型的客户互动开始。

    死党兴奋地移动着鼠标,能点的不能点的,都点了一遍。我站在背后,随着他鼠标的指向,做一些业务说明。

    5分钟过后,死党沉默了一会,开始吐嘈。

    “这是什么啊!”
    “这东西没法用!!”
    “我要的AABB的功能在哪里!!!”
    “这个XXX是什么意思?为什么要叫XXXX!!!!”
    等等等等。

    完全在我预期中的反应。

    对了,天底下所有的客户都是这德行。
    这么多年来,无论是什么项目,在第一次展示就得客户很高满意度的情况,几乎没有出现过。
    在第一次展示的时候,客户往往倾向于关注“还有什么没得到”,另外,还有一点,客户总是认为看到的,就是实际可用的,代表着你将要交付的软件。
    没有客户能理解”原型“这个词的意思,就算他们口头上哦哦啊啊的点头。

    ”这系统还不如我自己的EXCEL表好用呢“,死党嚷嚷着。
    切,就他那个古怪的连行列都分不清楚的EXCEL,如果不是身为老板的淫威不得不填,那二十几个销售人员早就把他爆菊无数次了。
    “你再录入几条数据试试,如果有重要的字段还没有建立,马上告诉我”。我转身走出他的办公室。

    所有重要的字段没有遗漏,这是我想要确认的信息。刚才在我几次催促下,死党确认了这点。

    从死党的角度来说,他的吐嘈点大部分都是成立的。因为,我直接使用了ADMIN来展示。而那个界面,基本不符合国人的风格和使用习惯。

    我选择了定制ADMIN模块来快速完成开发,我对ADMIN的印象太好了。

    好吧,终于来了。
    我真真正正要吐嘈的东西:DJANGO的ADMIN模块。

    我知道 DJANGO框架的灵活性不如别的框架,我也知道其开发团队也都说了ADMIN是设计为给”信任的用户"使用的。但不是有源码吗?我改源码行了吧,毕竟这次的系统没有特别复杂的需求。

    事实证明,我错得非常离谱。

    我TMD的干嘛要“基于ADMIN来定制“呢?如果是自己写VIEW,自己写URL响应,那么这一切都不发生,也就不会有本文。

    绝对不要试图基于ADMIN定制开发,并交付给最终用户使用。

    ADMIN是自我封闭的,实现指定功能的完整应用。
    虽然,可以通过重实现子类的函数来改变部分行为,但是,ADMIN的开发者压根就没想过”功能扩展“,几乎没有留下一丝的余地让你能做这些。

    也许是中西方的文化差异,声明的ADMIN应该被“信任的用户”使用,其实等同于:仅用于开发阶段的内测。也许这就是ADMIN被设计出来的目的,却被我借误应用在于”试图对其定制,以交付给最终用户“,这也是我在第一次发文,宣称的:把锤子当成榔头用。

    以上是总吐嘈,接下是细吐嘈。

    1. 权限系统

    死党需要的这套销售系统,唯一复杂的,就是”用户权限“。这跟销售员和公司的切身利益有关。但凡任何个人切身利益相关的事物,总会莫名的无比复杂。这也直接的反应到系统中。

    扯远一点,软件其实就是现实世界的影射,是用于解决现实世界中问题的。多才多艺,丰富的生活洞察力,是”优秀程序员“和”一般程序员“的最明显的区别之一。

    我们那个年代的程序员,除了个别外,绝对是很受妹子欢迎的。爱好文学,动手能力强,学习能力强,解决问题能力强,是通用的特征。此外,个个几乎都有独特的某项技能。
    记得有一个长几届的前辈,数字系博士,爱好推算买彩票,中奖的几率高得令人发指,但也没特别高金额的,几千最常见。
    还有一哥们,爱好读书,家里的书多得快把自己给挤出门口,博学尤其精通各国各种历史,曾经撰写一部穿越剧性质的计算机发展史,牛B的一塌糊涂,后来,太监了。
    而我,擅长做菜,尤其是海鲜类。千万别小看这一技能,这绝对是把妹第一利器,尤其达到针对不同妹子不同心情做出不同的菜的时候。
    那时,每到周六日,我家中就会聚集一堆妹子,偶尔会多出几个闻风而来的狼。
    海鲜味,交集着欢笑声喧哗声,飘散在整个楼层。
    永不会忘记,一个周日的早上,一个妹子,一头长发,一身长裙,左手抱着一只白猫,右手提着一口小锅,出现在门口。白猫是她的心爱宠物,所以要一起共享美味,而锅,则是要打包带走做为几天的口粮。也正是她在,在我25岁心情最不好的生日的时候,陪我去海边看月亮,呆了三天。
    真的好怀念,那个时候,那种心情。
    呵可,鼻子有点酸。

    回到DJANGO,继续吐嘈ADMIN。
    twor2
        51
    twor2  
       2012-09-04 14:39:28 +08:00
    看现场,插楼
    lambdaq
        52
    lambdaq  
       2012-09-04 14:50:11 +08:00
    admin挺好用的。前提是你把contrib.admin 所有代码过一遍。。
    jckwei
        53
    jckwei  
       2012-09-04 15:33:10 +08:00
    从python-cn googlegroups 过来插楼看吐槽。
    ZoomQuiet
        54
    ZoomQuiet  
       2012-09-04 15:36:51 +08:00
    CPyUG 团前来 Mark,,,
    很早就直觉的远离 Django,所以,一直无法精确的吐糟,,,现在,可以复用鸟!
    ZoomQuiet
        55
    ZoomQuiet  
       2012-09-04 15:38:29 +08:00
    @ZoomQuiet 嚓! V2EX 严重需要只看作者功能!
    felinx
        56
    felinx  
       2012-09-04 15:58:08 +08:00
    @ZoomQuiet 只看作者还不够的,另需要有脱水功能,楼主的思绪如脱缰野马。
    best1a
        57
    best1a  
       2012-09-04 16:31:39 +08:00
    - -谁写段js脚本然后把不是作者的回复都隐藏掉就好了
    ipconfiger
        58
    ipconfiger  
       2012-09-04 16:47:46 +08:00
    @felinx 这个......
    pyleaf
        59
    pyleaf  
       2012-09-04 17:05:45 +08:00
    貌似跟django没有半毛钱关系~~
    s_m
        60
    s_m  
       2012-09-04 17:59:37 +08:00
    CPyUG 团前来围观
    paloalto
        61
    paloalto  
       2012-09-04 18:08:29 +08:00
    我记得原先的v2ex是有只看楼主功能的啊。
    zyyzj
        62
    zyyzj  
    OP
       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
        63
    zyyzj  
    OP
       2012-09-04 19:39:31 +08:00
    @hzlzh dash很不错,但不适合查询页面跳转很频繁的内容。
    hzlzh
        64
    hzlzh  
    PRO
       2012-09-04 20:55:40 +08:00
    @zyyzj 今天两更了啊,不错。
    dash打开 stackoverflow 后前进后退的确有点弱,等更新新的按钮吧。
    PrideChung
        65
    PrideChung  
       2012-09-06 00:06:19 +08:00
    啊?这就完了?说好的悲剧呢?说好的兄弟反目妻离子散家破人亡自挂东南枝呢?
    xiaket
        66
    xiaket  
       2012-09-06 16:48:15 +08:00
    django的admin真的只能是给管理员用用, 要功能扩展肯定还是自己写视图函数靠谱. 之前也是在这个上面花了好多无谓的精力.

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

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

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

    哥,这个点,决然是吐错了的。
    imcj
        74
    imcj  
       2012-09-15 22:53:24 +08:00
    这个没有人定义这里不能连载小说吧。
    husw
        75
    husw  
       2014-03-22 22:59:46 +08:00
    曾经的0.96版...
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2771 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 30ms UTC 12:33 PVG 20:33 LAX 05:33 JFK 08:33
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86