0%

学习Django rest framework中遇到的一些问题及解决办法(持续更新)

问题一: yum update后挂载不了项目目录

解决办法
virtualbox和vagrant我都下的最新版,下的centos7.2box,添加box,初始化,启动,配置python和django环境都没问题,然后我更新了系统yum update,重启后就挂载不了项目目录了。需要按装插件vagrant plugin install vagrant-vbguest,然后vagrant reload就可以了。

问题二: 升级过python版本后pip安装提示SSL证书问题

解决办法

ubuntu下

apt-get install openssl
apt-get libssl-dev

其他系统有用yum的,一起把yum的也贴一下把

yum install openssl
yum install openssl-devel -y

下面就是重点了,更改安装文件Moudles/Setup里面的代码
下面代码执行的前提是当前路径是python3文件路径

vi Modules/Setup

然后更改里面的部分代码如下:

# Socket module helper for socket(2)
_socket socketmodule.c
# Socket module helper for SSL support; you must comment out the other
# socket line above, and possibly edit the SSL variable:
#SSL=/usr/local/ssl
_ssl _ssl.c \
-DUSE_SSL -I$(SSL)/include -I$(SSL)/include/openssl \
-L$(SSL)/lib -lssl -lcrypto

之后就进行一系列的更新就行了

问题三: 升级过python后pip安装的命令无法在命令行使用

解决办法
把升级过的python目录加入PATH中

问题四: vagrant目录中创建虚拟环境出错
提示

Traceback (most recent call last):
File "/usr/local/python3/bin/virtualenv", line 11, in <module>
sys.exit(main())
File "/usr/local/python3/lib/python3.6/site-packages/virtualenv.py", line 712, in main
symlink=options.symlink)
File "/usr/local/python3/lib/python3.6/site-packages/virtualenv.py", line 927, in create_e
nvironment site_packages=site_packages, clear=clear, symlink=symlink))
File "/usr/local/python3/lib/python3.6/site-packages/virtualenv.py", line 1389, in install
_python os.symlink(py_executable_base, full_pth)
OSError: [Errno 71] Protocol error: 'python' -> '/vagrant/devops/venv/bin/python3'

解决办法
虚拟环境在vagrant中的bug,加入–always-copy参数运行即可成功创建

This error can be fixed if you create the virtual env outside the /vagrant/ shared folder...

If go to the home folder of your vagrant user, you can create the virtualenv in there without this problem!

Just the venv must be out of this /vagrant/ directory... after that you can go work as usually activating this venv and working with your sorce code in the usual /vagrat/ shared dir.

问题五:手动python版本升级后yum等运行不正常

解决办法
在升级前做好备份工作,给原Python重命名成python_old,手动编辑/usr/yum文件,将其指向老版本的python,如:#!/usr/bin/python_old,这样yum运行的时候会找到老版本的Python,可以正常运行;同时修改/usr/libexec/urlgrabber-ext-down文件,修改方法同上。

问题六:UnicodeEncodeError: ‘ascii’ codec can’t encode characters in position 8-11: ordinal not in range(128)

解决方法
字符集问题,在程序开头加上:

reload(sys)
sys.setdefaultencoding( "utf-8" )

指定字符集即可解决。

问题七:在IDE的命令行下提示django.core.exceptions.ImproperlyConfigured: Requested setting INSTALLED_APPS, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings.

解决办法(待确认)
使用intelliJ Idea开发django项目,启动 manage.py 测试时,会出现如上所示问题。根据提示,有两种解决方法:

  1. define the environment variable DJANGO_SETTINGS_MODULE

在manage.py文件中添加

import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "你的project.settings")
  1. call settings.configure() before accessing settings

manage.py文件中添加

from django.conf import settings
settings.configure(DEBUG=True)

添加完代码后,检查是否修改项目的project structure设置

Project structure->Facets->Django->django project root:  ##你的django项目路径
settings: ##你的settings.py文件路径
manage.py script: manage.py
Environment variables: ##添写需要的环境变量

问题八: 导入django_filters不成功,提示No module named ‘django_filter’

解决方法
进入到虚拟环境, 输入pip list看到pip安装列表, 有django-filters 0.2.1, 看着没啥问题

手动进入到虚拟环境的site-packages目录:
cd ~/.virtualenvs/django_py3_1.11/lib/python3.5/site-packages/输入ll 命令查看目录所有文件
…/site-packages$ ll
发现只有’‘django_filters-0.2.1.dist-info’‘目录,并没有’‘django_filters’’, 而导入包的时候是需要找’‘django_filters’’, 证明包是有问题的
发现只有’’django_filters-0.2.1.dist-info’’目录,并没有’’django_filters’’, 而导入包的时候是需要找’’django_filters’’, 证明包是有问题的

阅读了README文档, 发现新版本的安装方式为:
pip install django-filter # 新版本安装后面不用s
卸载了原来的版本,再使用pip install django-filter安装了新版本, 然后问题就迎刃而解了, site-packages目录发生了变化
出现了django_filters目录,这样导包就不会有问题了

问题九: 在Django项目外使用其ORM模块

解决办法
在脚本开头加入如下内容:

#!/usr/bin/env python
import os
import sys

import django


if __name__ == '__main__':
dir = os.path.dirname(os.path.abspath(__file__))
dir = os.path.join(dir, 'db')
sys.path.insert(0, dir)
settings_path = 'db.settings'
os.environ.setdefault("DJANGO_SETTINGS_MODULE", settings_path)
django.setup()

之后就可以导入models操作数据库。

问题十:ERROR in ./node_modules/_element-ui@2.4.2@element-ui/lib/theme-chalk/fonts/element-icons.ttf

问题描述

ERROR in ./node_modules/_element-ui@2.4.2@element-ui/lib/theme-chalk/fonts/element-icons.ttf
Module parse failed: Unexpected character ' ' (1:0)
You may need an appropriate loader to handle this file type.
(Source code omitted for this binary file)
@ ./node_modules/_css-loader@0.28.11@css-loader!./node_modules/_element-ui@2.4.2@element-ui/lib/theme-chalk/index.css 7:411-447
@ ./node_modules/_element-ui@2.4.2@element-ui/lib/theme-chalk/index.css
@ ./src/main.js
@ multi ./node_modules/_webpack-dev-server@2.11.2@webpack-dev-server/client?http://localhost:8080 webpack/hot/dev-server ./src/main.js

解决办法
在webpack.config.js里配置

{
test: /\.(eot|svg|ttf|woff|woff2)$/,
loader: 'file-loader'
}

问题十一 python manage.py makemigrations运行时提示get_new_connection conn.encoders[SafeBytes] = conn.encoders[bytes] KeyError: <class 'bytes'>

解决办法
在PROJECTNAME目录下新建一个__init__.py文件,里面内容如下:

import pymysql
pymysql.install_as_MySQLdb()

重新创建数据库迁移文件即可。

问题十二 后端页面提示'CSRFCheck' object has no attribute 'process_request'

问题描述
django1.11.1版本使用APIView
from rest_framework.views import APIView
的时候(也出现过引入JWT的时候),后端前端会报错,
'CSRFCheck' object has no attribute 'process_request'

解决办法

方法一:
将Django版本升级到1.11.6以上:

pip install --upgrade django==1.11.6

方法二:
在settings.py文件中找到如下内容并注释:

...
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
# 'rest_framework.authentication.SessionAuthentication',
# 'rest_framework.authentication.BasicAuthentication',
)

问题十三: Django继承AbstractUser新建User Model时出现fields.E304错误

问题描述
makemigratios时出现:

auth.User.groups: (fields.E304) Reverse accessor forUser.groups’ clashes with reverse accessor forUser.groups’.
HINT: Add or change a related_name argument to the definition forUser.groupsorUser.groups’.
auth.User.user_permissions: (fields.E304) Reverse accessor forUser.user_permissions’ clashes with reverse accessor forUser.user_permissions’.
HINT: Add or change a related_name argument to the definition forUser.user_permissions’ orUser.user_permissions’.
users.User.groups: (fields.E304) Reverse accessor forUser.groups’ clashes with reverse accessor forUser.groups’.
HINT: Add or change a related_name argument to the definition forUser.groupsorUser.groups’.
users.User.head_url: (fields.E210) Cannot use ImageField because Pillow is not installed.
HINT: Get Pillow at https://pypi.python.org/pypi/Pillow or run command “pip install Pillow”.
users.User.user_permissions: (fields.E304) Reverse accessor forUser.user_permissions’ clashes with reverse accessor forUser.user_permissions’.
HINT: Add or change a related_name argument to the definition forUser.user_permissions’ orUser.user_permissions’.

解决办法
需要在setting中重载AUTH_USER_MODEL

AUTH_USER_MODEL = 'users.UserProfile'
users:appname
UserProfile:modelname

问题十四:Django执行manage.py migrate无效,提示No migrations to apply.

问题描述
已有的model,修改之后,想重新建模,于是将migrations文件夹中除__init__.py之外其他文件都删掉,再次执行以下步骤python manage.py makemigrations确认成功,执行python manage.py migrate,提示No migrations to apply. 表示一脸懵逼。

解决办法
造成多次应用migrations失败的原因是,当前model是修改过的,原来的migrations已经被我删除,但是,重新生成的migrations使用递增整数记名,所以,在django_migrations表中0001,0002等前面几个数字的文件都已被记录,在Django看来,被记录了就相当于已应用,所以,会出现刚开始的No migrations to apply.到数据库中删除相应记录和对应migration文件即可。即:

第一步:

删除该app名字下的migrations下的__init__.py等文件。

第二步:

进入数据库,找到django_migrations的表,删除该app名字的所有记录。

第三步:执行下面这两条命令:(在项目目录下)

python manage.py makemigrations

python manage.py migrate

问题十五:celery + redis执行异步任务时报错 AttributeError: ‘unicode’ object has no attribute ‘iteritems’

解决办法
如果python版本为2.7,将pip安装的reids库的版本降到2.X即可

问题十六: 在生产环境中使用gunicorn方式启动,Django的日志不能按正确的方式打印到设置的文件夹中

解决办法

目前经测试,使用如下的设置可以正常的输出日志文件到Django中设置的对应log目录:

  • 安装gunicorn后,在程序对应的目录下新建gunicorn_config.py文件,内容如下:
# coding=utf-8
import sys
import os
import multiprocessing

path_of_current_file = os.path.abspath(__file__)
path_of_current_dir = os.path.split(path_of_current_file)[0]
_file_name = os.path.basename(__file__)
sys.path.insert(0, path_of_current_dir)

worker_class = 'sync'
workers = multiprocessing.cpu_count() * 2 + 1 # 根据情况设置
chdir = path_of_current_dir

worker_connections = 1000
timeout = 30
max_requests = 2000
graceful_timeout = 30
loglevel = 'info'
reload = True
debug = False

bind = "%s:%s" % ("0.0.0.0", 8000)
pidfile = '%s/run/%s.pid' % (path_of_current_dir, _file_name)
errorlog = '%s/logs/%s_error.log' % (path_of_current_dir, _file_name)
accesslog = '%s/logs/%s_access.log' % (path_of_current_dir, _file_name)
  • 使用gunicorn -c方式指定刚写入的配置文件启动:
/home/qintianjun/hostinfo/venv/bin/gunicorn hostinfo.wsgi:application -c ./gunicorn_config.py --preload  # 加上preload参数是为了显示debug信息,可以省略

可以加上-daemon参数让gunicorn以后台方式启动

  • 确认Django中settings.py文件里的日志设置正确,参考:
# 记录日志
LOGBASEPATH = os.path.join(BASE_DIR, 'logs')
LOGPATH = os.path.join(LOGBASEPATH, time.strftime('%Y-%m-%d', time.localtime(time.time())))

if not os.path.exists(LOGPATH):
os.mkdir(LOGPATH)
......
# 定义具体处理日志的方式
'handlers': {
# 默认记录所有日志
'default': {
'level': 'INFO',
'class': 'logging.handlers.RotatingFileHandler',
'filename': os.path.join(LOGPATH, 'all-{}.log'.format(time.strftime('%Y-%m-%d'))),
'maxBytes': 1024 * 1024 * 5, # 文件大小
'backupCount': 5, # 备份数
'formatter': 'standard', # 输出格式
'encoding': 'utf-8'
},
......

这样Django日志会安照日期为目录建立在项目对应logs目录下

问题十七 修改过Django默认user模型后提示:django.db.migrations.exceptions.InconsistentMigrationHistory: Migration admin.0001_initial is applied before its dependency users.0001_initial on database 'default'.

解决方法
Since you are using a custom User model, your can first comment out
一旦你使用自定义的用户模型,你可以首先在INSTALL_APPS注释:

INSTALLED_APPS = [
...
#‘django.contrib.admin’,
...
]

然后执行迁移:

python manage.py migrate.

当迁移完成后再取消对它的注释:

‘django.contrib.admin’.

即可顺利迁移。

问题十八 今天在使用Git创建项目的时候,在两个分支合并的时候,出现了下面的这个错误。

~/SpringSpace/newframe onmaster11:35:56
$ git merge origin/druid
fatal: refusing to merge unrelated histories

问题分析

这里的问题的关键在于:fatal: refusing to merge unrelated histories ,因为你在本地和远程都创建了git仓库而他们之间没有联系。
你可能会在git pull或者git push中都有可能会遇到,这是因为两个分支没有取得关系。

解决方案

在你操作命令后面加--allow-unrelated-histories
例如:

git merge master --allow-unrelated-histories

~/SpringSpace/newframe on  druid ⌚ 11:36:49
$ git merge master --allow-unrelated-histories
Auto-merging .gitignore
CONFLICT (add/add): Merge conflict in .gitignore
Automatic merge failed; fix conflicts and then commit the result.

如果你是git pull或者git push报fatal: refusing to merge unrelated histories
同理:
git pull origin master --allow-unrelated-histories
就这样完美的解决咯!

问题十九 npm run eslint 报错

问题描述
在npm编译时eslint提示xxx warnings potentially fixable with the --fix option.

解决方案
报这个错是因为package.json中配置项少了 –fixed,更改为:

"lint": "eslint --fix --ext .js,.vue src",

继续运行,这里还有一些错是不能自动修复的,按ctrl单击,直接进到文件里,按照提示修改,比如这个报错声明但未定义的,直接删除或暂时注释掉就欧克了

问题二十 makemigrations出错,提示django.db.utils.OperationalError: (1071, 'Specified key was too long; max key length is 3072 bytes')

解决方案
由于 MySQL Innodb 引擎表索引字段长度的限制为 767 字节,因此对于多字节字符集的大字段(或者多字段组合索引),创建索引会出现上面的错误。

以 utf8mb4 字符集 字符串类型字段为例:utf8mb4 是 4 字节字符集,则默认支持的索引字段最大长度是: 767 字节 / 4 字节每字符 = 191 字符,因此在 varchar(255) 或 char(255) 类型字段上创建索引会失败。

可以尝试修改表的字符集:

ALTER DATABASE `databasename` CHARACTER SET utf8;

参考链接1

参考链接2

问题二十 Vue报错Custom elements in iteration require ‘v-bind:key’ directives.”

问题描述
错误代码

<i-option v-for="item in typeList" :value="item.value">{{ item.label }}</i-option>

解决方案

<i-option v-for="item in typeList" :key="item.label" :value="item.value">{{ item.label }}</i-option>

添加一个:key就可以了

问题二十一 Vue编译时报错TypeError: Cannot destructure property compile of 'undefined' or 'null'

问题描述
进入到VUE项目运行命令:npm run dev的时候报错。错误提示:TypeError: Cannot destructure property compile of ‘undefined’ or ‘null’

解决方案
经过分析,发现是因为webpack-dev-server版本过高导致。进入到项目中,运行如下命令:

npm install -D webpack-dev-server@3.0.0

然后再运行npm run dev即可。

问题二十二 使用requirements.txt安装python包时提示g++ error:/usr/lib/rpm/redhat/redhat-hardened-cc1 No that file and directory

解决方案

yum install gcc libffi-devel python-devel openssl-devel -y

sudo dnf install redhat-rpm-config

问题二十三 Django 2.x中创建Model时报以下错误:
TypeError: init() missing 1 required positional argument: ‘on_delete’

解决方案

定义外键的时候需要加上 on_delete=;
即:contract = models.ForeignKey(Contract, on_delete=models.CASCADE)

原因如下:
django 升级到2.0之后,表与表之间关联的时候,必须要写on_delete参数,否则会报异常:TypeError: init() missing 1 required positional argument: ‘on_delete’

附: on_delete各个参数的含义如下:

on_delete=None,               # 删除关联表中的数据时,当前表与其关联的field的行为
on_delete=models.CASCADE, # 删除关联数据,与之关联也删除
on_delete=models.DO_NOTHING, # 删除关联数据,什么也不做
on_delete=models.PROTECT, # 删除关联数据,引发错误ProtectedError
# models.ForeignKey('关联表', on_delete=models.SET_NULL, blank=True, null=True)
on_delete=models.SET_NULL, # 删除关联数据,与之关联的值设置为null(前提FK字段需要设置为可空,一对一同理)
# models.ForeignKey('关联表', on_delete=models.SET_DEFAULT, default='默认值')
on_delete=models.SET_DEFAULT, # 删除关联数据,与之关联的值设置为默认值(前提FK字段需要设置默认值,一对一同理)
on_delete=models.SET, # 删除关联数据,
a. 与之关联的值设置为指定值,设置:models.SET(值)
b. 与之关联的值设置为可执行对象的返回值,设置:models.SET(可执行对象)

由于多对多(ManyToManyField)没有 on_delete 参数,所以以上只针对外键(ForeignKey)和一对一(OneToOneField)

问题二十四 supervisorctl启动时报unix:///tmp/supervisor.sock no such file的问题

解决方案

1、打开配置文件

vim /etc/supervisord.conf
这里把所有的/tmp路径改掉,/tmp/supervisor.sock 改成 /var/run/supervisor.sock,/tmp/supervisord.log 改成/var/log/supervisor.log,/tmp/supervisord.pid 改成/var/run/supervisor.pid 要不容易被linux自动清掉

2、修改权限

sudo chmod 777 /run
sudo chmod 777 /var/log

如果没改,启动报错IOError: [Errno 13] Permission denied: '/var/log/supervisord.log'

3、创建supervisor.sock

sudo touch /var/run/supervisor.sock
sudo chmod 777 /var/run/supervisor.sock

4、启动supervisord,注意stop之前的实例或杀死进程

欢迎关注我的其它发布渠道