使用django从数据库反转成cms系统流程

目标:本文原目标为从已有的数据库表生成cms(后台管理)系统;也是使用django快速搭建一个网站的流程文档。


本地环境

不同环境下的操作步骤可能略有差异,先列出本文对应的配置环境以作区分。
开发环境
不同环境下的操作步骤可能略有差异,先列出本文对应的配置环境以作区分。

   
操作系统 Windows10 64bit
Python 2.7.11
Django 1.9.5

部署环境

   
操作系统 Linux CentOS 6.4 64bits Server
Python 2.7.11
Django 1.9.5
Apache 2.2.15
mod_wsgi 4.5.5

实现流程

下文介绍搭建、发布django项目的流程

环境搭建

下载python-2.7.11.amd64.msi安装python,配置环境变量。cms中输入python显示版本号则安装成功。
解压Django-1.9.5.tar.gz后进入文件夹根目录运行命令python setup.py install 安装django。
安装可参考http://www.ziqiangxuetang.com/django/django-install.html
编码和配置可以参考官方文档 https://docs.djangoproject.com/en/1.9/

新建项目与app

cms中使用命令:
进入想要生成项目的目录,
输入django-admin.py startproject xxx 来新建项目
进入项目目录,
输入python manage.py startapp xxx 新建app
这时候的目录结构会是
根目录
——项目名

——urls.py
——settings.py

——app名

——admin.py
——models.py

反转数据库表

安装mysql-connector-python-2.1.3-py2.7-winx64.msi (只能64位系统使用,否则安装时找不到python目录,32位可以从mysql官网http://dev.mysql.com/downloads/connector/python/下载)
目前上述mysqldb驱动在不支持python3,可以使用pymysql代替,代码上可以完全不变,只需要在项目同名目录下的urls.py中添加:

1
2
import pymysql
pymysql.install_as_MySQLdb()

更改settings.py的数据库连接配置,

1
2
3
4
5
6
7
8
9
10
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'database name’,
'USER':’user name’,
'PASSWORD':'password',
'HOST':'ip',
'PORT': 'port',
}
}

cmd中运行python manage.py inspectdb (>directory) 反转数据库,如果没有报错的话,控制台/指定目录中就已经生成了翻转后的model代码。
运行python manage.py makemigrations , python manage.py migrate 同步数据库,django会自动在数据库中生成用户及历史记录相关表,如下
Alt text
如果数据表需要更新,或者想使用model生成表时,依然使用这两个命令python manage.py makemigrations , python manage.py migrate更新数据库。
python manage.py migrate 是执行app下的文件夹migrations下的.py文件,如果migrate命令一直在报错,可能是某个py文件的更改与数据库表的状态不同步(例如python manage.py makemigrations后又更改了表结构),那么删掉冲突后的文件,重新makemigrations,就可以解决持续报错的问题。

配置模型

在项目中注册app,在settings.py中加入app

1
2
3
4
5
6
INSTALLED_APPS = [
.
.
.
'pcms', #app名
]

为了决定cms中有哪些模型需要被管理,app目录下的admnin.py中,加入如下代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from .models import  Article             #article是model名
class ArticleAdmin(admin.ModelAdmin): #如果不配置以下内容,这里的class申明可以不需要
#列表显示项
list_display = ('page_title', 'last_update_date','type')
#新增和修改时的可编辑项
fields = ('content',)
#过滤项,group by
list_filter = ('type',)
#搜索项
search_fields = ('page_title',)
#每一页显示数目
list_per_page = 10

admin.site.register(Article, ArticleAdmin)

更多配置参考 https://docs.djangoproject.com/en/1.9/ref/contrib/admin/actions/

启动服务器

cms中使用python manage.py createsuperuser创建超级管理员,按照提示输入用户名邮箱密码就可以了。
python manage.py runserver 或者 python manage.py runserver 端口号 开启服务器,访问’http://localhost:8000/admin或者http://localhost:端口号/admin/ 进入cms。

更改页面模板

settings.py中设置TEMPLATES=[…]中的dirs可以设置项目模板路径,设置成

1
'DIRS': [os.path.join(BASE_DIR,'templates'),],

指定basedir为根目录下的templates文件夹。在自己的项目根目录下建立templates\admin两个文件夹,用于存放自定义html模板。
python安装目录下的
Python27\Lib\site-packages\Django-1.9.5-py2.7.egg\django\contrib\admin\templates\admin
文件中夹中的html文件都是cms使用的html模板,可以从那里复制文件到templates\admin下并改写。其中{%xxx%}标签进行模块表示、逻辑判断,{{xxx}}标签代表context传到模板里的变量。 配置成功后,django就会优先使用templates\admin下的自定义模板来展示界面了。

配置静态资源根目录(开发状态)

页面中如果需要使用自定义的css、js、图片等,需要配置静态资源路径。
在自动生成的项目中,如下两个配置项应该都已经配置好了:
settings.py的STATIC_URL = ‘/static/‘ 和 INSTALLED_APPS里的 ‘django.contrib.staticfiles’,
现在要做的只有在app下建立目录\static\admin\css,在其中添加自己的css,然后在模板中通过类似于

1
<link rel="stylesheet" type="text/css" href="{% static "admin/css/changelists.css" %}" />

引用。要注意的是,如果自定义css和Python27\Lib\site-packages\Django-1.9.5-py2.7.egg\django\contrib\admin\static\admin\css
下的css文件重名,那么django会优先使用python目录下的,目前我还没发现怎么更改优先级,所以不能重名。

CMS的控件扩展

下拉选择框

更改models.py,先加入选择框属性

1
2
3
4
STATUS_PUBLISH = (
(0, 'UnPublished'),
(1, 'Published'),
)

然后将选择框应用到属性中去

1
2
class Event(models.Model):   
publish = models.IntegerField(choices=STATUS_PUBLISH,…)

这个属性对应的编辑项就是下拉框了

多选框

这个控件需要多对多的表关联
对于数据库表反转生成的项目,我在models.py文件里加入的关联关系在生成表的时候会因为表名前缀冲突而失败,还没有找到解决办法。最好先在表中添加多对多关系,然后反转。
上面的bug可以通过安装South管理model更改来避免http://www.ziqiangxuetang.com/django/django-schema-migration.html
默认多选框的效果是这样的:

但是这个在可选项变多时不大好选择,可以在admin.py中更改ModelAdmin类来更改样式,例如:

1
2
3
class BookAdmin(admin.ModelAdmin):

filter_horizontal = ('authors',)

这时样式会变成
Alt text

同理filter_vertical = (‘verticals’,) 样式就是竖过来的。

文件上传

models.py中,更改变量类型

1
models.FileField(upload_to = …)

对应的表单域就变为文件上传控件了
类型改为ImageField限制为图片上传
后台限值文件上传或大小TODO,预测需要自定义上传方法

服务器部署

目前已知有apche和uwsgi两种部署方式,本文在项目中使用过的是apache+mod_wsgi的部署方式。

部署前准备:

所需版本的python源码包、django源码包 、数据库驱动pymysql的源码包、apache模块mod_wsgi的安装包、项目中导入的第三方包列表(如果服务器不连外网则需要源码包和它们引用到的所有源码包)

部署步骤:

关掉selinux,安装mysql。
因为centos上都有旧版本的python,所以先更新python版本,要保留旧版本python推荐看这篇博客:http://www.cnblogs.com/lanxuezaipiao/archive/2012/10/21/2732864.html。
注意该篇博客中的

1
./configure --prefix=/usr/local/python3

要改成

1
./configure --enable-shared --prefix=/usr/local/python3

来确保安装动态链接库。安装后运行python命令看到版本为自己需要的就行了。
编译安装apache和mod_wsgi(apache也可以用yum安装,比较快捷,但是目前内网的apache版本有点旧)。编译安装mod_wsgi后,修改配置文件httpd.conf,添加如下一行:
LoadModule wsgi_module modules/mod_wsgi.so
用来加载wsgi服务。
安装和配置apache和mod_wsgi容易抛的错比较多,包括缺少依赖软件、配置文件出错、没找对网站默认存放目录……安装后最好实际检验一下:
测试是否配置成功,创建一个test.wsgi文件(wsgi文件就是一个python module,只不过扩展名是wsgi而已),文件内容如下:

1
2
3
def application(environ,start_response):
start_response("200 OK",[('content-type',"text/html")])
return ['<html><body>Hello world!</body></html>']

修改httpd.conf配置文件,添加下面一行:

1
WSGIScriptAlias /trac  目录/test.wsgi

重启apache服务器
在地址栏敲入http://127.0.0.1/trac,如果输出“hello world”说明配置成功
然后就是配置自己的项目了,其实要改的只有一个httpd的配置文件,目的是在最后加上
WSGISocketPrefix /var/run/wsgi
WSGIScriptAlias / /var/www/workhours/workhours/wsgi.py
WSGIPythonPath /var/www/workhours/
WSGIDaemonProcess gongshitongji.tp-link.net python-path=/var/www/workhours/:/usr/local/python27/lib/python2.7/site-packages
WSGIProcessGroup gongshitongji.tp-link.net

Alias /static/js/ /var/www/workhours/static/js/
Alias /static/css/ /var/www/workhours/static/css/
WSGISocketPrefix /var/run/wsgi
WSGIScriptAlias / 项目目录/wsgi.py
WSGIPythonPath 项目目录
WSGIDaemonProcess gongshitongji.tp-link.net
python-path=项目目录:python目录/site-packages
WSGIProcessGroup gongshitongji.tp-link.net

Alias /static/js/ 项目目录/static/js/
Alias /static/css/ 项目目录/static/css/
Alias /static/admin/ django目录/static/admin

<Directory /var/www/workhours/workhours/>

Order deny,allow
Allow from all

<Directory /var/www/workhours/static/js>

Order deny,allow
Allow from all

<Directory /var/www/workhours/static/css>

Order deny,allow
Allow from all


这段配置定义了项目目录,静态文件目录。可以直接写在httpd.conf后面也可以自定义一个配置文件然后在httpd.conf中引用。
然后,重启apache,查看项目是否运行成功!
一般这个时候是打开django的报错页面,这时候打开apache的error.log可以看到为什么报错(一般是引用到的包没有找到),然后像开发时一样解决这些报错。
报错解决后,更改settings.py为

1
2
DEBUG=false
ALLOWED_HOSTS = ['*']

就算发布成功了

国际化

admin的国际化可以在settings.py中设置,例如下面配置为中文。

1
LANGUAGE_CODE = 'zh-hans'

某些特定文字还可以通过“更改页面模板”中的手法来更改。models.py中的字段和模型本身的verbose_name也是很重要的汉化手段。