Django 1.10 升级到 2.1的问题

引子

之前写的一些东西时间有点久了,想升级一下Django版本

升级Django

requestments.txt

1
2
3
4
5
6
7
8
Django>=2.0,<3.0
mysqlclient
psycopg2
djangorestframework
markdown
django-filter
django-allauth
django-bootstrap3

执行命令

1
pip install -r requestments.txt

尝试运行 runserver

1
./manage.py runserver localhost:5000

发现以下问题

1. 外键关联语法错误

1
2
3
  File "E:\projects\python\dweb\web\smanager\models.py", line 50, in Employee
user = models.OneToOneField(User)
TypeError: __init__() missing 1 required positional argument: 'on_delete'

原因:

在django2.0后,定义外键和一对一关系的时候需要加on_delete选项,此参数为了避免两个表里的数据不一致问题,不然会报错:
TypeError: init() missing 1 required positional argument: ‘on_delete’
举例说明:
user=models.OneToOneField(User)
owner=models.ForeignKey(UserProfile)
需要改成:
user=models.OneToOneField(User,on_delete=models.CASCADE) –在老版本这个参数(models.CASCADE)是默认值
owner=models.ForeignKey(UserProfile,on_delete=models.CASCADE) –在老版本这个参数(models.CASCADE)是默认值
参数说明:
on_delete有CASCADE、PROTECT、SET_NULL、SET_DEFAULT、SET()五个可选择的值
CASCADE:此值设置,是级联删除。
PROTECT:此值设置,是会报完整性错误。
SET_NULL:此值设置,会把外键设置为null,前提是允许为null。
SET_DEFAULT:此值设置,会把设置为外键的默认值。
SET():此值设置,会调用外面的值,可以是一个函数。
一般情况下使用CASCADE就可以了。

修改:

即在外键值的后面加上 on_delete=models.CASCADE

2. 引入包名错误

1
2
3
4
5
6
7
8
9
10
11
  File "<frozen importlib._bootstrap>", line 994, in _gcd_import
File "<frozen importlib._bootstrap>", line 971, in _find_and_load
File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 678, in exec_module
File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
File "E:\projects\python\dweb\web\smonitor\urls.py", line 21, in <module>
from smanager import views as sm_views
File "E:\projects\python\dweb\web\smanager\views.py", line 7, in <module>
from django.core.urlresolvers import reverse
ModuleNotFoundError: No module named 'django.core.urlresolvers'

原因:

django.core.urlresolvers 在 Django2中被修改,可以找 django.urls

修改 :
from django.core.urlresolvers import reverse -> from django.urls import reverse

3. 启动服务之前需要首先运行python manage.py migrate

1
2
You have 14 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them.

4. 运行时错误

1
2
3
4
5
6
7
8
9
10
11
Internal Server Error: /
Traceback (most recent call last):
File "D:\apps\python36\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
response = get_response(request)
File "D:\apps\python36\lib\site-packages\django\core\handlers\base.py", line 126, in _get_response
response = self.process_exception_by_middleware(e, request)
File "D:\apps\python36\lib\site-packages\django\core\handlers\base.py", line 124, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "E:\projects\python\dweb\web\smanager\views.py", line 27, in index
if request.user.is_authenticated() == False :
TypeError: 'bool' object is not callable

方法修改成属性 request.user.is_authenticated() –> request.user.is_authenticated

‘WSGIRequest’ object has no attribute ‘session’,这个问题是因为settings中middleware的定义参数变了,得把MIDDLEWARE_ClASSES改成MIDDLEWARE。

5.

其他注意事项

MIDDLEWARE:
新版本中 中间件的key值 由 MIDDLEWARE_CLASSES 变更为 MIDDLEWARE

render_to_response:
新版本中 render_to_response 不建议使用,替换为render

dict的’has_key’方法弃用:
新版python字典 has_key 方法取消,建议使用 “str” in dict 判断