在配置Django的时候常常会出现一些问题,比如migrate无效,表单提交valid验证不过等问题,本文给出了一些解决方案
同步数据库的问题
根据不同版本有对应以下两种方法同步数据库:
1 | python manage.py syncdb |
(用于旧版本)
1 | python manage.py makemigration |
(用于新版本)
其中migrate
方法一般要提前建一个空的数据库,但是数据表是自动同步的
自定义数据表
一般地,django在数据库中存储的表名为model name,但是可以通过以下方式自定义表名
1 | class MyModel(models.Model): |
上传文件问题
- 上传空文件会导致is_valid不过
- 不能在如view.py, model.py中正常地import
这些文件的sys.path中的当前目录是manage.py所在目录,一般比这些文件本身所在的目录高一级。所以sys.path.append
中的路径应当比实际高一层。
同样因为这个原因,保存文件时路径不能以’/upload/‘开头,而应该直接以’upload/‘开头。在外部程序访问时,应当做一个路径转化。
Migrate问题
RuntimeError: Error creating new content types. Please make sure contenttypes is migrated before trying to migrate apps individually.
检查Model.pyContentType
模型对应数据库中django_content_type
表,主要用户维护django project中所安装的所有用户模型
出现这个问题一定是模型问题,我后来发现我的原因是因为models.XXXField
里面多了一些参数比如required
什么的删掉就好,此外form也要注意
之后一定要先drop database
再migrate就可以了file clean之后变成None
摘自C:\Program Files (x86)\Python27\Lib\site-packages\Django-1.9-py2.7.egg\django\forms\forms.py1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48def full_clean(self):
"""
Cleans all of self.data and populates self._errors and
self.cleaned_data.
"""
self._errors = ErrorDict()
if not self.is_bound: # Stop further processing.
return
self.cleaned_data = {}
# If the form is permitted to be empty, and none of the form data has
# changed from the initial data, short circuit any validation.
if self.empty_permitted and not self.has_changed():
return
self._clean_fields()
self._clean_form()
self._post_clean()
def _clean_fields(self):
for name, field in self.fields.items():
# value_from_datadict() gets the data from the data dictionaries.
# Each widget type knows how to retrieve its own data, because some
# widgets split data over several HTML fields.
if field.disabled:
value = self.initial.get(name, field.initial)
else:
value = field.widget.value_from_datadict(self.data, self.files, self.add_prefix(name))
try:
if isinstance(field, FileField):
initial = self.initial.get(name, field.initial)
value = field.clean(value, initial)
else:
value = field.clean(value)
self.cleaned_data[name] = value
if hasattr(self, 'clean_%s' % name):
value = getattr(self, 'clean_%s' % name)()
self.cleaned_data[name] = value
except ValidationError as e:
self.add_error(name, e)
def _clean_form(self):
try:
cleaned_data = self.clean()
except ValidationError as e:
self.add_error(None, e)
else:
if cleaned_data is not None:
self.cleaned_data = cleaned_data看了半天源码发现,
python的小坑
python是没有select
/switch
语句的,为了避免很麻烦的if-elif-else,可以采用{condition:value}[statement]
近似替代select
/switch
语句,这个小坑在于,所有的condition:value都会被求值,所以一方面会降低性能,一方面要考虑副作用的问题了。
字符集的小坑
request.GET.get
得到的参数是unicode,必须先转换类型才能使用哦
HttpResponse的小坑
HttpResponse不能正确处理array object的情况,例如下面的代码是不能得到正确的结果的哦:
1 | return HttpResponse([ |
运行发现前端得到的是这样的数据:
解决方案是当遇到对象数组的时候使用json.dump()函数将它转化为json,然后返回application/json格式的HttpResponse,如return HttpResponse(json_stuff, content_type ="application/json")
,当然千万注意前端ajax拿到data之后就不要eval了。
转义
Django和Angular等框架合用需要注意转义:
openblock { %
closeblock % }
templatetag openvariable { {
templatetag closevariable } }
openbrace {
closebrace }
opencomment { #
closecomment # }
Angular的问题
这边顺便说一下Angular和jQuery混合使用常犯的一个错误:
1 | $.ajax({ |
如上代码$scope是不能更新的,因为success函数不在angular的名字空间里面了。
Python urllib2的问题
使用以下代码抓取网页
1 | def getHtml(url): |
发现报502错,这时候检查一下自己的翻墙软件是不是全局代理,这边我的Shadowsocks开启了全局代理,urllib2就不能抓https://127.0.0.1:8091了,502报错
1 | urllib2.HTTPError: HTTP Error 502: Server dropped connection |
Django + Nginx + Https
这里有一个非常大的坑,如果使用本机调试的话,千万不要选择localhost,而应该选择127.0.0.1.
因为localhost可以是[::1]也可以是127.0.0.1,详见 这里 和 这里
如果使用了localhost,那么会造成1min左右的加载问题,最初我以为是static files的问题,后来查看了error发现是 *24 upstream timed out (10060: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond) while connecting to upstream, client: 127.0.0.1, server: localhost
,这种问题一般都是写了localhost。
–推荐以下blog