Django项目升级拾遗

据说总结晚一周知识就会流失30% →_→

近期利用空闲时间(jia ban)把自己负责健身会议管理系统Django版本从1.6升级到了1.10,Python版本从2.7升级到了3.6。总结下升级的过程和遇到的问题吧(然而拖了两周才动笔基本忘得差不多了Orz

要点

先说结论,赶时间的话之后的内容就没必要看了(反正写的也不好= =

每个项目使用的语法特性不一样,升级的版本也不同。对于不大的项目,一个比较好的方式是对于本地能正常运行的项目,升级完依赖包后启动,然后google+stackoverflow驱动改提示的错误,直到能正常使用为止。

升级历程

其实刚到公司实习的时候见着老旧的依赖版本就想着能不能升级,由于经验不足和处理的过于激进失败了。一年多后才想起可以再尝试下

介绍下项目背景,会议系统是公司里代码量最小(Pyhton代码近2万行),也没有历史包袱,和其他项目之间依靠RPC协议通信的项目。基本实现了前后端分离,除了最早期的几个移动端页面。大部分代码都是业务相关的API,使用了内部的(伪)RESTful框架。迁移相对比较容易。

首先升级Django以及其他依赖包的版本,把依赖的包都升级到最新的版本,启动项目= =,毫无悬念的失败了。google+stackoverflow驱动改错下跌跌撞撞的改完能整除启动项目……居然完全可用。再解了数据库迁移的坑Django版本迁移就成功了。

关于数据库迁移,如果是新起一个实例的话就是用新的数据库迁移方法,只要保证APP下有migration这个包就行了。已经在线上运行的实例就麻烦些,要先去线上删掉旧的migration文件。

然后是Python版本的升级,替换茫茫然的unicode字符串和__future__就已经很坑了,还好有自动化工具帮我们完成这件事,我使用了自带的工具2to3,转换效果还是相当好的。剩下的地方基本都是str和bytes的问题了

之前也看了很多人写的升级备忘。不过每个人使用的语法特性不一样,升级的版本也不同。除非是翻译文档,否则没人写的全的(所以我偷懒把写的提纲删了,参考资料里有一些他人的踩坑记录)

Model

移除South

Django1.7之后提供了内建的数据库迁移工具,可以把south从INSTALLED_APPS移除了

对于新的实例

和新的项目一样

1
2
python manager.py makemigrations
python manager.py migrate

旧数据迁移

  • 确保south中的migration全部被应用了
  • 从 INSTALLED_APPS中移除south
  • 删除每个app下migration目录中的所有文件, 除了init.py
  • 运行python manager.py makemigrations, Django会初始化migration
  • 运行python manager.py migrate –fake, django将migration文件标记为已应用

Python2 -> Python3

2to3 自动完成的事情

  • 删除了 from __future__ import division, unicode_literals, print_function
  • 字符串 u’’ -> ‘’ unicode() > str()
  • 常用写法
    hasattr(self.order_by, '__iter__') -> isinstance(self.order_by, (list, tuple))
    value.has_key('selected') -> 'selected' in value
    except Exception, err: -> except Exception as err:
  • 部分lambda表达式转换成列表表达式
    map(lambda x: x.to_json(), meeting_objs) -> [x.to_json() for x in meeting_objs]
  • 一些包引用方式的改变
    import cStringIO StringIO -> import io
    import urllib -> import urllib.request, urllib.parse, urllib.error

参考资料


Django项目升级拾遗
https://blog.kdwycz.com/archives/upgrade-django-project/
作者
kdwycz
发布于
2017年3月22日
许可协议