Djang1.8+Python2.0迁移到Django2.0+Python3.6注意事项
参考:https://blog.csdn.net/weixin\_40475396/article/details/82971541
1. 编码
unicode,str,bytes在python2和python3中的叫法以及相互转换,具体为:
- 在Python3中的str对象在Python2中叫做unicode,但 bytes 对象在Python2中叫做str,如果想得到一个文本字符串,需要在字符串之前加上前缀 u 或者decode一下。
- 项目中的问题:① python2项目中字符串前加的u可以去掉了,因为在python3中就是一个文本字符串,也就是str对象,②获取阿里云签名的视图函数,涉及到编码问题,需要处理
- 编码问题参考:https://blog.csdn.net/yanghuan313/article/details/63262477
2. Model外键
- python3中Model中字段的外键必须设置on_delete,一般设置为
on_delete=models.DO_NOTHING
,代表删除与关联内容无关 - 同一张表多个字段引用相同的外键需要设置related_name
- Model外键问题参考:https://blog.csdn.net/lht\_521/article/details/80605146
3. 判断是否是匿名用户
- django1.8.2是is_anonymous()
- django2.0是is_anonymous
4. Exception
python2捕获异常是:
try:
Exception,e
pass
python3捕获异常是:
try:
Exception as e
pass
raise异常直接写字符串到异常中,例如:
python2:
raise SimpleAjaxException,'Return data should be follow the Simple Ajax Data Format'
python3:
raise SimpleAjaxException('Return data should be follow the Simple Ajax Data Format')
5. urls.py
静态文件收集:
django1.8:url(r'^static/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.STATIC_ROOT})
django2.0:
from django.views.static import serve
url( r'^static/(?P
.*)$', serve, {'document_root': settings.STATIC_ROOT})
导入的文件时,同目录下,不能再直接import了,使用from . import **,
绝对导入相对导入参考:https://www.jianshu.com/p/5cc20b88bcf4
6. 中间件类继承
- django1.8.2继承的是object
- django2.0继承的是MiddlewareMixin,导入方法:
from django.utils.deprecation import MiddlewareMixin
7. 字典Dict
- Python 3.0 内的另一个重大改变是字典内dict.iterkeys(),dict.itervalues(),dict.iteritems()方法的删除。取而代之的是:dict.keys(),dict.values(),dict.items()
- dict.has_key()在Python2中存在,但是在Python3中更改为__contains__
8. seetings设置
- Django1.8.2中间件配置名称是MIDDLEWARE_CLASSES,Django2.0是MIDDLEWARE
9. 缓存问题
- Python2和Python3对换错的哈希方式不同,上线的时候最好是把缓存清一下。
Bug:上线Python3,因为用户系统问题,上线失败,退回到Python2,此时因为有Python3的缓存,而版本是Python2的版本,导致报错。
解决方式:清除缓存。
10. 用户系统问题
如果两个项目共用一个用户系统,Django2.0项目的用户在登陆状态,如果此时Django1.8项目登陆此用户,再次刷新Django2.0项目的此用户,就需要重新登录。
此问题是因为Django1.8和2.0中间件对哈希的密码校验问题不同导致的request请求时,对象中的 session_id
消失,最终导致数据库中session被清除,目前能暂时解决,绕过这个问题,尚未找到根本原因。
解决办法:
1)在用户表的Model里面添加方法,相当于撤回到python2的验证机制,强制绕过这个登陆时校验密码hash之后跟缓存中的hash密码是否一致。
def getattribute(self, item):
if item == 'getsessionauthhash':
raise AttributeError
return super().getattribute_(item)
- 回归到第一条,校验用户时,对密码hash,是通过一个固定的值加密码hash的,django1.8和2.0这个固定的值不同,导致密码hash之后跟缓存中的hash密码不一致,如果将不同版本的这个值设为相同的话,就ok了,其实settings.py里面就可以设置,只是不同版本有默认值,就没有在显示设置。如下:
PASSWORD_HASHERS = [ 'core.hasher.CustomPBKDF2PasswordHasher']
然后再相对于的路径创建文件重写类:比如上面就是在core文件夹下的hasher.py文件重写CustomPBKDF2PasswordHasher类:
from django.contrib.auth.hashers import PBKDF2PasswordHasher
class CustomPBKDF2PasswordHasher(PBKDF2PasswordHasher):
iterations = 20000