Django@Python 3常见问题

Django@Python 3常见问题
环境搭建及常见配置
详情可参见Django环境搭建及开发

# 如果同时安装了Python 2和Pyhton 3要指定版本
mkvirtualenv -p python3 env
或
mkvirtualenv --python=python3路径 env

pip install django mysqlclient
pip install django-crispy-forms django-formtools httplib2

虽然很多领域如机器学习的开发者当前更青睐于Python 2,但Python 3已经被越来越多的开发者们所使用,本文旨在整理Python 3环境下安装最新Django版本所出现的问题,其中有很多内容和Python 2下相似或相同。

1.用户表重写

在继承AbstractUser表重写该类时会提示Reverse accessor for ‘User.*’ clashes with reverse accessor for ‘*.*’

auth.User.groups: (fields.E304) Reverse accessor for 'User.groups' clashes with reverse accessor for 'UserProfile.groups'.
	HINT: Add or change a related_name argument to the definition for 'User.groups' or 'UserProfile.groups'.
auth.User.user_permissions: (fields.E304) Reverse accessor for 'User.user_permissions' clashes with reverse accessor for 'UserProfile.user_permissions'.
	HINT: Add or change a related_name argument to the definition for 'User.user_permissions' or 'UserProfile.user_permissions'.

解决这一问题只需要按照你定义的app名称和类名在settings.py中添加如下内容:

Read More

Django RESTful API搭建及常见问题

Django中内置的有一些Json数据的处理和返回方案

myModels = MyModel.objects.all()
# 1.model直接转换为dict
from django.forms.models import model_to_dict
for myModel in myModels:
    json_dict = model_to_dict(myModel)
    json_list.append(json_dict)
# 2. 直接序列化并通过JsonResponse和HttpResponse返回
from django.core import serializers
import json
json_data = serializers.serialize('json', myModels)
json_data = json.loads(json_data)

from django.http import HttpResponse, JsonResponse

# return HttpResponse(json.dumps(json_data), content_type="application/json")
return JsonResponse(json_data, safe=False)

# 注:在工作中出现调用系统外的SQL Server来获取数据,通过以下方式可返回Json
cur = cursor.fetchall()
from django.core.serializers.json import DjangoJSONEncoder
json_data = json.dumps(cur, cls=DjangoJSONEncoder)
return HttpResponse(json_data, content_type="application/json")

虽然看似以上方案也可以打造我们的API,但更为灵活的Rest API方案还是应该要采用Django REST framework

安装

除djangorestframework, markdown, django-filter外,建议同时安装coreapi,django-guardian, 环境搭建参照Django环境搭建及开发

mkvirtualenv -p /usr/local/bin/python3 myproject
pip install django djangorestframework markdown django-filter mysqlclient pillow
# urls.py
from rest_framework.documentation import include_docs_urls
url(r'docs/', include_docs_urls(title="")),
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),

Serializer

使用步骤一、在对应App下新建serializers.py

from rest_framework import serializers
# 方法一、指定字段
class ModelNameSerializer(serializers.Serializer):
    name = serializers.CharField(max_length=100, required=True)
    num = serializers.IntegerField(default=0)
# 方法二、ModelSerializer(更推荐),其中__all__表示输出所有字段,也可通过传递数组/列表来指定字段
from .models import ModelName
class ModelNameSerializer(serializers.ModelSerializer):
    class Meta:
        model = ModelName
        fields = "__all__"
# 扩展,如果model拥有外键,那么实际只会输出相应的id,要输出其中的内容,可以新建另一个Serializer来实现内嵌输出,如上述更改为:
from .models import ModelName, Model2Name
class Model2NameSerializer(serializers.ModelSerializer):
    class Meta:
        model = Model2Name
        fields = "__all__"
class ModelNameSerializer(serializers.ModelSerializer):
    fieldName = Model2NameSerializer()
    class Meta:
        model = ModelName
        fields = "__all__"

使用步骤二、Views.py

# 方法一
from .models import ModelName
from .serializers import ModelNameSerializer
from rest_framework.views import APIView
from rest_framework.response import Response


class ModelNameList(APIView):
    """
    Your description
    """
    def get(self, request, format=None):
        model_name = ModelName.objects.all()
        serializer = ModelNameSerializer(modelName, many=True)
        return Response(serializer.data)
# 方法二
from .models import ModelName
from .serializers import ModelNameSerializer
from rest_framework import mixins, generics


class ModelNameList(mixins.ListModelMixin, generics.GenericAPIView):
    """
    Your description
    """
    queryset = ModelName.objects.all()
    serializer_class = ModelNameSerializer

    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)
# 方法三
from .models import ModelName
from .serializers import ModelNameSerializer
from rest_framework import generics


class ModelNameList(generics.ListCreateAPIView):
    """
    Your description
    """
    queryset = ModelName.objects.all()
    serializer_class = ModelNameSerializer

分页

# 配置方法一(settings.py)
REST_FRAMEWORK = {
    'PAGE_SIZE': 10
}
# 配置方法二(Views.py)
from rest_framework.pagination import PageNumberPagination

class ModelNamePagination(PageNumberPagination):
    page_size = 10
    page_size_query_param = 'page_size'
    max_page_size = 100
    page_query_param = 'p'

class ModelNameList(generics.ListCreateAPIView):
    ...
    pagination_class = ModelNamePagination

ViewSet

用法一

# Views.py
from rest_framework import viewsets, mixins
# 习惯性地将上述ModelNameList修改为ModelNameListViewSet
class ModelNameListViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):

# urls.py用法一
modelname_list = ModelNameViewSet.as_view({
    'get': 'list',
})
urlpatterns = [
    url(r'modelname/$', modelname_list, name="goods_list"),
]
# urls.py用法二(更推荐)
from rest_framework.routers import DefaultRouter

router = DefaultRouter()
router.register(r'modelname', ModelNameListViewSet)
urlpatterns = [
    url(r'^', include(router.urls)),
]

过滤、搜索、排序

# 方法一、在ViewSet中定义如下方法
def get_queryset(self):
...
# 方法二、 
# 注意:这里过滤使用的是django-filter,而搜索、排序则使用的是DRF自身的filters
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import filters
filter_backends = (DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter)
filter_fields = ('field_name1', 'field_name2')
search_fields = ('field_name1', 'field_name2')
ordering_fields = ('field_name1',)
# 注:在Django的配置中使用tuple如果只有一个元素建议在最后加一个逗号,否则会导致配置失效,因为不加逗号会将其视为字符串类型

# 升级方案,创建filters.py
import django_filters
from .models import Product
class ProductFilter(django_filters.rest_framework.FilterSet):
    min_price = django_filters.NumberFilter(name="price", lookup_expr='gte')
    max_price = django_filters.NumberFilter(name="price", lookup_expr='lte')

    class Meta:
        model = Product
        fields = ['min_price', 'max_price']
# 在ViewSet中添加
filter_class = ProductFilter

跨域访问

API通常都是由不同域名来进行调用,此将会出现如下报错 Failed to load resource: the server responded with a status of 504 (Gateway Timeout) Django的解决方案如下

# 1.安装django-cors-headers
pip install django-cors-headers
# 2.settings.py
MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',
#请放在CsrfViewMiddleware之前
    ...
]

CORS_ORIGIN_ALLOW_ALL = True
# 或通过CORS_ORIGIN_WHITELIST设置白名单

权限认证

Token配置

# settings.py
INSTALLED_APPS = (
    ...
    'rest_framework.authtoken'
)

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.BasicAuthentication',
        'rest_framework.authentication.SessionAuthentication',
        'rest_framework.authentication.TokenAuthentication',
    )
}

# urls.py
from rest_framework.authtoken import views
urlpatterns += [
    url(r'^api-token-auth/', views.obtain_auth_token)
]

# 执行makemigrations 和 migrate生成Token相关数据表

# View内Token认证,注释DEFAULT_AUTHENTICATION_CLASSES中的Token部分,添加
authentication_classes = (TokenAuthentication,)

请求时的header为Authorization: Token 虽然Django REST Framework(DRF)的Token非常强大,但存在着无有效期、一旦泄露则面临风险,因此有人根据JWT规范开发一个REST framework JWT的认证方式,安装配置也很简单

pip install djangorestframework-jwt
# settings.py
REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        ...
        'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
    )
}

import datetime
JWT_AUTH = {
    'JWT_REFRESH_EXPIRATION_DELTA': datetime.timedelta(days=7),
    'JWT_AUTH_HEADER_PREFIX': 'JWT',
}

# urls.py
from rest_framework_jwt.views import obtain_jwt_token
urlpatterns = [
    ...
    url(r'^api-token-auth/', obtain_jwt_token),
]

请求时的header为Authorization: JWT

权限控制

AllowAny
IsAuthenticated
IsAdminUser
IsAuthenticatedOrReadOnly
DjangoModelPermissions
DjangoModelPermissionsOrAnonReadOnly
DjangoObjectPermissions API暴露太多权限(POST, PUT)时需谨慎

#官方文档中给出的示例是这样的
class XxxViewSet(viewsets.ModelViewSet):
#只需将ModelViewSet修改成ReadOnlyModelViewSet即可变为只读
class XxxViewSet(viewsets.ReadOnlyModelViewSet):

常见问题 1.Cannot apply DjangoModelPermissions on a view that does not set .queryset or have a .get_queryset() method. 很明显这是Django Rest Framework的权限导致某些接口页面无法访问,所以自然而然地大多数人会告诉你进行如下修改

'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.AllowAny'
    ],

Read More

Django使用七牛云保存图片

Django使用七牛云保存图片

最近在使用Django写项目,考虑将图片放到七牛云上,使用xadmin进行后台管理。我们都知道在models中使用ImageField可以直接生成数据表,其中的upload_to直接设置上传路径,这样在django的admin或xadmin中可以直接完成上传,但这种上传只能上传到本地,于是在网上搜到了下文,非常简单有效:

Read More

Django未登录跳转登录页面设置

在Django的实际应用中,我们通常会限制某些页面在登录后方可访问(如个人中心页面),否则就跳转到登录页面先进行登录。

在网上搜索到的直接使用装饰器@login_required放在view上方的做法当前版本(1.9.*以上)并不可用,会报以下错误:

AttributeError: 'function' object has no attribute 'as_view'

那么该如何实现呢?以index页面为例,实现方法有以下几种:

1.url+view文件

#urls.py,以下xxx为书写view的app名称
from xxx.views import IndexView
url(r'^$', IndexView.as_view(), name="index"),
#views.py
from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator
@method_decorator(login_required, name='dispatch')
class IndexView(View):
    def get(self, request):
        return render(request, 'index.html', {})

2.仅url文件

from django.contrib.auth.decorators import login_required
url(r'^$', login_required(TemplateView.as_view(template_name="index.html")), name="index"),

3.LoginRequiredMixin

# views.py,以下xxx为书写view的app名称
from django.contrib.auth.mixins import LoginRequiredMixin
class IndexView(LoginRequiredMixin, View):
    def get(self, request):
        return render(request, 'index.html', {})

# urls.py
from xxx.views import IndexView
url(r'^$', IndexView.as_view(), name="index"),

注:默认登录页面为/accounts/login/,如需更改,请在settings.py文件中进行相应的更改,如

#login_required URL
LOGIN_URL = '/login/'

Django及Xadmin开发代码速查

本文接Django环境搭建及开发一文,旨在记录一些常用的开发代码避免经常要到官方文档中查看(为方便操作大多在PyCharm[ Tools> Run manage.py Task…]中进行,涉及命令行的可以自行在前面添加python manage.py)。

注:如果在菜单中找不到Run manage.py Task的话,请点击Preferences>Languages & Frameworks>Django在右侧Settings处配置本项目的setting.py文件位置

另外以下内容涉及中文的如使用Python 2.x请自定添加u来指定为utf-8编码

基本操作篇

1.创建App

startapp app_name

2.在系统settings.py的INSTALLED_APPS中添加对应的app_name

class ModelName(models.Model):
# 注:xxx = models.DateTimeField(default=datetime.now)时不要在now后加括号

3.编辑所创建App下的models.py(数据表的创建)

makemigrations app_name
migrate app_name

createsuperuser创建后台登录的超级用户

4.添加url(urls.py)

from django.views.generic import TemplateView
urlpatterns = [
    url(r'^xadmin/', xadmin.site.urls),
    url(r'^$', TemplateView.as_view(template_name='index.html'), name="index"),
]

5. forms和views常用
views.py

# 反向取外键所有数据(_set)
yourObject.theModelName_set.all()
# 获取url的name并跳转
from django.core.urlresolvers import reverse
return HttpResponseRedirect(reverse('index'))

forms.py

class Meta:
    model = modelName
    fields = ['field1'...]
# 在使用ModelForm时通clean_fieldName来重写该字段验证方法, 在该方法内获取字段值:self.cleaned_data['fieldName']

Settings.py的常见修改

# 将所有app都放到apps下后的设置
import sys
sys.path.insert(0, os.path.join(BASE_DIR, 'apps'))
# 配置数据库
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'test',
        'USER': 'root',
        'PASSWORD': 'root',
        'HOST': '127.0.0.1',
        'OPTIONS': {
            'init_command': "SET storage_engine=INNODB;",
        },
    }
}
# 设置模板目录
TEMPLATES = [
    {
        'DIRS': [os.path.join(BASE_DIR, 'templates')]
    },
]
# 设置文字
LANGUAGE_CODE = 'zh-hans'
# 设置时区
TIME_ZONE = 'Asia/Shanghai'
USE_TZ = False

STATICFILES_DIRS = (
    os.path.join(BASE_DIR, 'static'),
)
# 设置上传使用的media路径
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
# 同时配合的配置还有
TEMPLATES = [
    {
        'OPTIONS': {
            'context_processors': [
                ....
                'django.template.context_processors.media',
            ],
        },
    },
]
# 设置media路径时应设置urls.py
from ProjectName.settings import MEDIA_ROOT
from django.views.static import serve
url(r'^media/(?P<path>.*)$', serve, {"document_root": MEDIA_ROOT}),

用户信息表

用户信息表略有特殊之处:
models.py

 

CentOS 7下通过uWSGI + Nginx部署Django

安装Python 3

wget https://www.python.org/ftp/python/3.6.0/Python-3.6.0.tgz
tar -xzvf Python-3.6.0.tgz -C  /tmp
cd  /tmp/Python-3.6.0/
./configure --prefix=/usr/local
make && make altinstall

安装Nginx

#add the CentOS 7 EPEL repository(/etc/yum.repos.d/)
sudo yum -y install epel-release
#安装Nginx
sudo yum -y install nginx
#启动Nginx
sudo systemctl start nginx
#如果运行了防火墙执行如下命令允许http和https的web访问
sudo firewall-cmd --permanent --zone=public --add-service=http 
sudo firewall-cmd --permanent --zone=public --add-service=https
sudo firewall-cmd --reload
#开机启动Nginx服务
sudo systemctl enable nginx

在浏览器中访问http://server_domain_name_or_IP/如果出现如下页面表明Nginx安装正常
Nginx启动页面
Nginx主配置文件:/etc/nginx/nginx.conf,可以看网站默认根目录在/usr/share/nginx/html,可通过在/etc/nginx/conf.d下添加.conf文件进行配置

安装MySQL

#安装MySQL,由于直接通过yum安装将会安装的是MariaDB
#需访问https://dev.mysql.com/downloads/repo/yum/查找对应的版本
wget https://dev.mysql.com/get/mysql57-community-release-el7-9.noarch.rpm
rpm -ivh mysql57-community-release-el7-9.noarch.rpm
yum install -y mysql-server mysql-devel
#启动MySQL服务
systemctl start mysqld
#查找安装初始密码
grep 'temporary password' /var/log/mysqld.log
#修改密码删除多余的测试表
mysql_secure_installation

安装virtualenvwrapper

yum -y install python-setuptools python-devel
yum -y install python-pip
pip install virtualenvwrapper
#如果出现因安装过慢所导致的失败,进行如下配置
cd ~
mkdir .pip
cd .pip
vi pip.conf 
#放入如下内容保存退出
[global]  
index-url = https://pypi.doubanio.com/simple/  
[install]  
trusted-host=pypi.doubanio.com  
disable-pip-version-check = true  
timeout = 6000  

#也可在安装时直接使用pip install -i https://pypi.douban.com/simple package_name

编辑家目录下的.bashrc文件设置如下环境变量

export WORKON_HOME=$HOME/.virtualenvs
#可不设置export PROJECT_HOME=$HOME/project_directory
source /usr/bin/virtualenvwrapper.sh 
#重载.bashrc
source  ~/.bashrc
#新建虚拟环境
mkvirtualenv test

#过入本机,导出本地环境安装包
workon xxx
pip freeze > requirements.txt
#上传requirements.txt需部署机器
workon test
pip install -r requirements.txt


#安装uwsgi
pip install uwsgi

测试uwsgi是否安装正常

方法一: 创建test.py文件,添加如下代码

def application(env, start_response):
        start_response('200 OK', [('Content-Type','text/html')])
        return "Hello World"
#执行如下代码
uwsgi --http :8001 --wsgi-file test.py

浏览器访问http://your-ip:8001输出Hello World表示安装正常
方法二:

django-admin startproject testProject
cd testProject
uwsgi --http :8000 --module testProject.wsgi

浏览器访问http://your-ip:8000输出It worked页面表示安装正常

以上方法如无法访问,可能需要关闭防火墙:systemctl stop firewalld
如果从本地打包上传,在testProject/settings.py

#将DEBUG值修改为False
#注释以下部分
#STATICFILES_DIRS = [
#    os.path.join(BASE_DIR, 'static')
#]
#添加如下代码
STATIC_ROOT = os.path.join(BASE_DIR, 'static')

执行 python manage.py collectstatic

Nginx配置

在testProject主目录下创建uc_nginx.conf然后创建软链接
sudo ln -s 你的目录/testProject/uc_nginx.conf /etc/nginx/conf.d/
或者直接在/etc/nginx/conf.d/下创建uc_nginx.conf:

# the upstream component nginx needs to connect to
upstream django {
# server unix:///path/to/your/mysite/mysite.sock; # for a file socket
server 127.0.0.1:8000; # for a web port socket (we'll use this first)
}
# configuration of the server

server {
# the port your site will be served on
listen      80;
# the domain name it will serve for
server_name 192.168.0.16 www.yourdomain.com; # substitute your machine's IP address or FQDN
charset     utf-8;

# max upload size
client_max_body_size 75M;   # adjust to taste

# Django media
location /media  {
    alias /root/testProject/media;  # 指向django的media目录
}

location /static {
    alias /root/testProject/static; # 指向django的static目录
}

# Finally, send all non-media requests to the Django server.
location / {
    uwsgi_pass  django;
    include     uwsgi_params; # the uwsgi_params file you installed
}
}

#ssl配置
server {
# the port your site will be served on
listen   443;
ssl on;
ssl_certificate   /home/cert/yourcert.pem;
ssl_certificate_key  /home/cert/yourkey.key;
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
# the domain name it will serve for
server_name www.yourdomain.com; # substitute your machine's IP address or FQDN
charset     utf-8;

# max upload size
client_max_body_size 75M;   # adjust to taste

# Django media
location /media  {
    alias /root/testProject/media;  # 指向django的media目录
}

location /static {
    alias /root/testProject/static; # 指向django的static目录
}

# Finally, send all non-media requests to the Django server.
location / {
    uwsgi_pass  django;
    include     /root/testProject/conf/uwsgi_params; # the uwsgi_params file you installed
}
}

重启Nginx
注:使用systemctl restart nginx.service有可能会出现权限问题

些时使用pkill -f nginx,执行如下命令启动nginx

sudo /usr/sbin/nginx

在根目录下/root/testProject添加conf/uwsgi.ini

# mysite_uwsgi.ini file
[uwsgi]

# Django-related settings
# the base directory (full path)
chdir           = /root/testProject
# Django's wsgi file
module          = testProject.wsgi
# the virtualenv (full path)

# process-related settings
# master
master          = true
# maximum number of worker processes
processes       = 10
# the socket (use the full path to be safe
socket          = 127.0.0.1:8000
# ... with appropriate permissions - may be needed
# chmod-socket    = 664
# clear environment on exit
vacuum          = true
virtualenv = /root/.virtualenvs/test
~                                     

启动

uwsgi -i /root/testProject/conf/uwsgi.ini &

Django的配置



接下来配置站点下的settings.py中数据库部分,创建app


python manage.py startapp blog
python manage.py makemigrations
python manage.py migrate

系统就会创建一些django默认表格,同样地可以测试启动站点

python manage.py runserver 0.0.0.0:9000

uwsgi

uwsgi --http :8000 --home /root/.virtualenvs/test --chdir /root/testsite/ -w testsite.wsgi
#停止所有uwsgi服务
ps -ef |grep uwsgi |awk '{print $2}'|xargs kill -9
#或使用如下命令自动关闭并重启
pkill -f uwsgi

设置定时任务

 

常见问题

1.Exception: you need a C compiler to build uWSGI
或Failed building wheel for mysql-python

yum install gcc  
//或执行
yum groupinstall "Development tools"

http://11hcw.me/setting-up-django-and-cloud-server-with-uwsgi-and-nginx/

2.environmenterror mysql_config not found

yum install -y mysql-devel

3.‘WSGIRequest’ object has no attribute ‘user’

访问http://your_ip:8000/admin时出现如上报错,将settings中的MIDDLEWARE改为MIDDLEWARE_CLASSES可以修复这一问题
4.出现以下报错需先安装MySQL

Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-build-vMcjZK/MySQL-python/
# 注:Python 3尚不能直接支持MySQL-python,请使用pip install mysqlclient

5.出现以下错误yum install gcc -y

error: command 'gcc' failed with exit status 1
  
  ----------------------------------------
  Failed building wheel for MySQL-python

6.ImportError: cannot import name patterns
根据提示找到对应文件,如Alan这里是由一个Ueditor插件所致,找到DjangoUeditor/urls.py删除掉patterns的import并修改掉urlpattern的写法

from django.conf.urls import patterns, url
修改为
from django.conf.urls import url
urlpatterns = patterns('',
    url(r'^controller/$',get_ueditor_controller)
)
修改为
urlpatterns = [
    url(r'^controller/$',get_ueditor_controller)
]

7.TemplateDoesNotExist
将本地项目移到线上,UEditor会报错,关闭调试在后台中查看详情或添加时均会报Server Error (500)
Exception Type: TemplateDoesNotExist
Exception Value: ueditor.html
相信会有更好的解决方法,Alan的处理方式是将相关的模板文件以及静态文件拷贝到对应目录

/root/.virtualenvs/yourproject/DjangoUeditor/templates/* extra_apps/xadmin/templates/
cp -R /root/.virtualenvs/yourproject/DjangoUeditor/static/* static/

参考文章:

初识Nginx

如何将django项目用Nginx部署到服务器

Django环境搭建及开发

开发工具:PyCharm

 

环境配置

#mac下环境配置
sudo easy_install pip
sudo -H pip install virtualenv
sudo easy_install virtualenvwrapper
source /usr/local/bin/virtualenvwrapper.sh //可加入.bash_profile等文件启动执行,找不到可通过sudo find / -name virtualenvwrapper.sh查找
# 在.bash_profile或.bashrc下还可配置默认虚拟环境存放路径
export WORKON_HOME=$HOME/.virtualenvs # windows下添加WORKON_HOME环境变量
mkvirtualenv env1
//切换虚拟环境
workon env1
pip install django //指定版本sudo -H pip install Django==1.9.8
//安装MySQL组件
pip install mysql-python
//退出虚拟环境
deactivate
//其它命令
lsvirtualenv -b
lssitepackages
cdvirtualenv
cdsitepackages
rmvirtualenv env1
cpvirtualenv env1 env2
#安装Xadmin,需在settings.py的INSTALLED_APPS添加xadmin, crispy_forms
pip install xadmin
#Captcha
pip install  django-simple-captcha==0.4.6

注:
手动源码安装xadmin时需额外安装依赖包

pip install django-crispy-forms django-formtools httplib2

使用多Python版本需要指定版本:

#设置别名(.bash_profile),如
alias python3='/Users/alan/anaconda/bin/python3.5'
#默认Python 2
mkvirtualenv -p python env4
或
mkvirtualenv --python=python2路径 env4
#Python 3
mkvirtualenv -p python3 env5
或
mkvirtualenv --python=python3路径 env5

 

注:使用Anaconda搭建虚拟环境

conda search "^python$"
conda create -n yourenvname python=x.x anaconda
conda info -e
source activate yourenvname
source deactivate
conda remove -n yourenvname -all

常用命令

#创建项目
django-admin startproject myproject
#创建应用
cd myproject
python manage.py startapp blog
#PyCharm Run manage.py Task或在命令切的到目录执行python manage.py ...
#创建应用,如message,创建后需在settings.py的INSTALLED_APPS中进行添加
startapp message
#先配置settings.py中DATABASES的参数
#        'ENGINE': 'django.db.backends.mysql',
#        'NAME': 'dbname',
#        'USER': 'root',
#        'PASSWORD': 'password',
#        'HOST': '127.0.0.1',
makemigrations
migrate
runserver
#创建后台管理员账号
createsuperuser

小技巧:
执行python manage.py sqlmigrate 应用名(如mesage) 0001(migrations文件夹下的序号)可以查看原生的SQL的语句
执行migrate指令后默认生成的表格:

执行migrate指令后默认生成的表格

xadmin操作

adminx.py配置

注:在后台如需导出excel格式文件需安装xlwt(pip install xlwt),如需导出xlsx格式的则请安装xlsxwriter

#可选择不同主题
class BaseSetting(object):
    enable_themes = True 
    use_bootswatch = True
#注册配置
xadmin.site.register(views.BaseAdminView, BaseSetting)

class GlobalSettings(object):
    site_title = "后台管理系统" #设置后台左上角名称
    site_footer = "Alan Hou"   #设置后台footer的文字
    menu_style = "accordion"   #左侧导航的收缩显示
xadmin.site.register(views.CommAdminView, GlobalSettings)

将后台中主菜单的英文修改为中文,以app名users为例

#apps的UsersConfig类下添加
verbose_name = u"用户信息"
#__init__.py下添加
default_app_config = "users.apps.UsersConfig"

xadmin中的延伸配置

#后台默认排序
ordering = ['-click_nums']
#后台不可修改字段
readonly_fields = ['click_nums']
#后台隐藏字段
exclude = ['fav_nums']
#可以ajax请求的外键(后台中搜索)
relfield_style = 'fk-ajax'

Model及数据库操作

models.py部分内容示例

#执行makemigrations, migrate指令会进行创建、修改和删除的操作
class UserMessage(models.Model):
    object_id = models.CharField(max_length=50, default="", primary_key=True, verbose_name=u'主键')
    name = models.CharField(max_length=20, null=True, blank=True, default="", verbose_name=u'用户名')
    email = models.EmailField(verbose_name=u'邮箱')
    address = models.CharField(max_length=100, verbose_name=u'联系地址')
    message = models.CharField(max_length=500, verbose_name=u'留言信息')

    # 常用Field类型
    # models.ForeignKey
    # models.DateTimeField
    # models.IntegerField
    # models.IPAddressField
    # models.FileField
    # models.ImageField

    class Meta:
        verbose_name = u'用户留言信息'
        verbose_name_plural = verbose_name
        # db_table = '' 指定数据表名
        # ordering = '-object_id' 默认排序

AutoField, BigAutoField, BigIntegerField, BinaryField, BooleanField, CharField, CommaSeparatedIntegerField, DateField, DateTimeField, DecimalField, DurationField, EmailField, FileField, FileField and FieldFile, FilePathField, FloatField, ImageField, IntegerField, GenericIPAddressField, NullBooleanField, PositiveIntegerField, PositiveSmallIntegerField, SlugField, SmallIntegerField, TextField, TimeField, URLField, UUIDField, ForeignKey, ManyToManyField, OneToOneField

 

null, blank, choices, db_column, db_index, db_tablespace, default, editable, error_messages, help_text, primary_key, unique, unique_for_date, unique_for_month, unique_for_year, verbose_name, validators

views.py中原生SQL语句示例

# 原生SQL语言
# def book_list(request):
#     db = MySQLdb.connect(user='root', db='djangoT', passwd='', host='127.0.0.1')
#     cursor = db.cursor()
#     cursor.execute('SELECT name FROM books ORDER BY name')
#     name = [row[0] for row in cursor.fetchall()]
#     db.close()

注:代码中使用中文需在文件开始指定编码为utf-8

 # -*- coding: utf-8 -*-

表单提交数据需添加

#不添加提交表单会提示CSRF token missing or incorrect.
{% csrf_token %}

如果创建应用比较多,可以创建一个apps的package,把所有应用放在里面,但这样会要求有import时前面加上一个apps,在PyCharm中把apps右键Mark为Sources Root,在settings.py中加入以下代码以避免在命令行中执行时报错

import sys
sys.path.insert(0, os.path.join(BASE_DIR, 'apps'))

常见问题

1.Bad Request (400)
需配置项目下的settings.py中的ALLOWED_HOSTS,如下例局域网中可通过http://192.168.1.3:9999进行访问

#启动服务,可指定任意未占用的端口
python manage.py runserver 0.0.0.0:9999
#settings.py
ALLOWED_HOSTS=['192.168.1.3']

2.libmysqlclient.18.dylib问题

Reason: unsafe use of relative rpath libmysqlclient.18.dylib in /Users/alan/.python-eggs/MySQL_python-1.2.5-py2.7-macosx-10.12-intel.egg-tmp/_mysql.so with restricted binary

#网上多数人给出的解决方案,我的机器上使用未解决
sudo install_name_tool -change libmysqlclient.18.dylib \
/usr/local/mysql/lib/libmysqlclient.18.dylib \
/Users/alan/.python-eggs/MySQL_python-1.2.5-py2.7-macosx-10.12-intel.egg-tmp/_mysql.so

3.Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)
参见Stackoverflow上的回答

P.S.操作别忘了备份数据库哦

4.ValueError: unknown locale: UTF-8

raise ValueError('unknown locale: %s' % localename)
ValueError: unknown locale: UTF-8

在.bash_profile或其它文件中添加如下并source

export LC_ALL=en_US.UTF-8
export LANG=en_US.UTF-8

5.pip install速度过慢
在安装时会出现速度太慢,甚至导致无法完成的现象,这时可尝试进行如下配置

cd ~
mkdir .pip
cd .pip
vi pip.conf 
#放入如下内容保存退出
[global]  
index-url = https://pypi.doubanio.com/simple/  
[install]  
trusted-host=pypi.doubanio.com  
disable-pip-version-check = true  
timeout = 6000  

也可在安装时直接使用
pip install -i https://pypi.doubanio.com/simple/ xxx

6.Error fetching command ‘collectstatic’
运行manage.py任务时出现如下报错,并未发现影响到使用

Error fetching command 'collectstatic': You're using the staticfiles app without having set the STATIC_ROOT setting to a filesystem path.
Command 'collectstatic' skipped

如需解决,在settings.py中添加

STATIC_ROOT = os.path.join(BASE_DIR, 'static')

7.IntegrityError: (1452, ‘Cannot add or update a child row:
在使用Django Admin后台添加用户时出现如下报错:

IntegrityError: (1452, 'Cannot add or update a child row: a foreign key constraint fails (<code>mxonine</code>.<code>django_admin_log</code>, CONSTRAINT <code>django_admin_log_user_id_c564eba6_fk_auth_user_id</code> FOREIGN KEY (<code>user_id</code>) REFERENCES <code>auth_user</code> (<code>id</code>))')
[26/Dec/2016 19:50:05] &quot;POST /admin/users/userprofile/add/ HTTP/1.1&quot; 500 196219

一个解决方案是在settings.py的DATABASES版块添加如下代码取消外键检查

'OPTIONS': {
         "init_command": "SET foreign_key_checks = 0;",
    },

8.页面样式(静态文件)导入不成功,在settings.py的最后加入

STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static')
]

9.表单input中显示None
在value中添加default_if_none,这样就会显示placeholder中的内容

value="{{ forget_form.email.value|default_if_none:'' }}"

10.global name ‘_’ is not defined
添加

from django.utils.translation import ugettext as _

11.dyld: Library not loaded: @rpath/libpython3.5m.dylib

此错误通常发生在同时使用Anaconda配置了Python的其它环境,最简单的解决方法是指定Python版本:

mkvirtualenv -p /usr/bin/python xxxx

# homebrew默认安装的是最新版本的python,如当前brew install python3会安装3.6版本,但由于3.5显然拥有更多的库可以使用,可参照:
brew tap zoidbergwill/python
brew install python35
mkvirtualenv --python=/usr/local/Cellar/python35/3.5.2/bin/python3.5 env

12.setup.py: Not using bundled FreeTDS
这一错同样出现在Mac上,安装pymssql需依赖FreeTDS,按照pymssql官方文档的提示仅需执行brew install freetds,但安装时却会出现错误,解决方法是:

brew unlink freetds
brew install homebrew/versions/freetds091
pip install pymssql

13.
django.db.utils.OperationalError: (1366, “Incorrect string value
出现以上错误请记得将数据库的字符集修改为utf8,Collation修改为utf8_general_ci
MySQL Strict Mode is not set for database connection ‘default’
出现以上错误在DATABASES配置(settings.py)中添加:

'OPTIONS': {
    'init_command': "SET sql_mode='STRICT_TRANS_TABLES'",
},

14.(1146, “Table ‘***.****’ doesn’t exist”)
a. 删除对应的表格(如果有数据请确保备份数据)
b. 在models.py中注释相关model
c. 执行如下命令

makemigrations
migrate --fake

d. 在models.py中取消相关model注释
e. 执行如下命令

makemigrations
migrate

15.PyCharm激活

网上的激活码基本都已失效,PyCharm确实比较贵,有条件地请支持正版,想体验付费版可以通过在VPS上运行如下代码获取License Server:

wget http://home.ustc.edu.cn/~mmmwhy/jetbrain.sh &amp;amp;&amp;amp; sh ./jetbrain.sh

其它破解方法: http://idea.lanyus.com/

16. Windows下进行pip安装出现类似下面这样的报错

Could not find function xmlCheckVersion in library libxml2

访问http://www.lfd.uci.edu/~gohlke/pythonlibs/找到对应的包(如此处搜索libxml)并完成载先用pip install+下载的文件名安装后再执行安装

17.unicode argument expected, got ‘str’

import io
#Python 2
io.BytesIO()
#Python 3
io.StringIO()