前言
许久未见Django,若不是因为一个急切的需求,估计近期也不会重玩Django。具体需求是,需要构建一个能够连接远端数据库,并且能够增删改查数据,不觉想到了Django的admin。
考虑之后,决定在本地完成Django的基础数据,就是用户,分组等初始化数据,然后设置多数据库,连接远端数据反馈到admin。
开发环境,ubuntu 14.04,python2.7.6,Django1.8.9,mysql 5.5.22,apache,wsgi
Django 多数据库
Django中文官网给出了示例用法。
http://python.usyiyi.cn/django/topics/db/multi-db.html
其中给出了较为详细的多数据库用法,此处仅为实现具体需求,选择用app数据路由配置方法。
1,先建立工程,配置setttings.py文件DATABASES:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'localdb',
'USER': 'root',
'PASSWORD': '',
'HOST': '127.0.0.1',
'PORT': '3306',
},
'remote': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'hrdb',
'USER': 'root',
'PASSWORD': '',
'HOST': 'remote_host',
'PORT': '3306',
}
}
2,配置数据库路由,个人做法在manage.py同层新建root.py文件,内容如下:
class DefaultRouter(object):
"""
A router to control all database operations on models in the
auth application.
"""
def db_for_read(self, model, **hints):
"""
Attempts to read auth models go to auth_db.
"""
if model._meta.app_label == 'auth':
return 'default'
return None
def db_for_write(self, model, **hints):
"""
Attempts to write auth models go to auth_db.
"""
if model._meta.app_label == 'auth':
return 'default'
return None
def allow_relation(self, obj1, obj2, **hints):
"""
Allow relations if a model in the auth app is involved.
"""
if obj1._meta.app_label == 'auth' or \
obj2._meta.app_label == 'auth':
return True
return None
def allow_migrate(self, db, app_label, model=None, **hints):
"""
Make sure the auth app only appears in the 'auth_db'
database.
"""
if app_label == 'auth':
return db == 'default'
return None
class MediaRouter(object):
"""
A router to control all database operations on models in the
hr application.
"""
def db_for_read(self, model, **hints):
"""
Attempts to read media models go to hrdb.
"""
if model._meta.app_label == 'hr':
return 'remote'
return None
def db_for_write(self, model, **hints):
"""
Attempts to write media models go to hrdb.
"""
if model._meta.app_label == 'hr':
return 'remote'
return None
def allow_relation(self, obj1, obj2, **hints):
"""
Allow relations if a model in the hr app is involved.
"""
if obj1._meta.app_label == 'hr' or \
obj2._meta.app_label == 'hr':
return True
return None
def allow_migrate(self, db, app_label, model=None, **hints):
"""
Make sure the auth app only appears in the 'hrdb'
database.
"""
if app_label == 'hr':
return db == 'remote'
return None
如果远端表已经存在,不要再执行migrate操作,请不要设置allow_migrate.
在Django中以app名称,app_modelname的形式建表的。app hr中的models.py文件如下:
from django.db import models
class Media(models.Model):
longtext = models.CharField('长文字--longtext', max_length=2048, blank=True, default='')
title = models.CharField('模板标题--title', max_length=128, blank=True, default='')
sub_title = models.CharField('模板子标题--subtitle', max_length=128, blank=True, default='')
attrs = models.CharField('地图--attrs',
max_length=1024, blank=True, default='')
res_id = models.IntegerField('模块资源--res_id', blank=True, default=0)
def __unicode__(self):
return '%s %s' % \
(self.id, self.res)
Media models对应的表为hr_media,那么如何将其和MediaRouter联系起来?
在root.py中指定了auth和hr app中对应的数据库,在settings.py中添加配置:
# 数据库路由
DATABASE_ROUTERS = ['root.DefaultRouter', 'root.MediaRouter']
# 静态文件路径
STATICFILES_DIRS = (
(os.path.join(os.path.dirname(__file__), "../static")).replace("\\", "/"),
)
# 时区
TIME_ZONE = 'Asia/Shanghai'
基本完成工程设定,运行也行完成了需求。
服务器配置
mysql
sudo apt-get install mysql-server mysql-client
sudo apt-get install libmysqlclient-dev
安装过程中默认安装了mysql 5.5.52版本,存在一张表中不能定义多timestamp字段,建议使用高版本mysql。亲试在5.7.16中没有问题。
apache + wsgi
sudo apt-get install apache2
sudo apt-get install libapache2-mod-wsgi
sudo service apache2 start
安装好的apache启动后,可以在浏览器中访问
机器地址+默认80端口
的地址,即表示apache以正常安装。
python
sudo apt-get install python-dev
pip install MySQL-python
pip intall django==1.8.9
配置
工程配置
在工程中添加wsgi.py文件,新建的Django工程在settings.py文件的同级中有,但是要稍作配置,添加工程到path中,wsgi.py配置如下:
import os
import sys
from django.core.wsgi import get_wsgi_application
sys.path.append((os.path.join(os.path.dirname(__file__),"my_project")).replace("\\","/"))
path = '~/PycharmProjects/my_project'
if path not in sys.path:
sys.path.append(path)
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "my_project.settings")
application = get_wsgi_application()
apache2配置
ubuntu中apache安装位置在
Listen 8888
<VirtualHost *:8888>
ServerName 192.168.1.109
#ServerAlias www.example.com
DocumentRoot /var/www/html
# log 输出为之配置
ErrorLog "~/PycharmProjects/my_project/error.log"
CustomLog "~/PycharmProjects/my_project/access.log combined"
# wsgi.py 许可配置
WSGIScriptAlias / "~/PycharmProjects/my_project/wsgi.py"
<Directory ~/PycharmProjects/my_tornado>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
# 静态文件配置
Alias /static "~/PycharmProjects/my_project/static"
<Directory ~/PycharmProjects/my_project/static>
Require all granted
</Directory>
</VirtualHost>
admin配置
admin静态文件配置
需求中需要用admin的静态文件,这个是python Django包中自带的,所以在工程中,需要链接admin中静态文件到工程的static中:
ln -s /usr/local/lib/python2.7/dist-packages/django/contrib/admin/static/admin admin
这样admin就能够加载所有的静态文件了,不在时光秃秃的裸界面了。
admin界面配置
在Django admin.py注册文件中,可以另外配置界面显示效果,admin.py内容如下:
from django.contrib import admin
from models import Media
class MediaAdmin(admin.ModelAdmin):
# 表格表头
list_display = ('id', 'title', 'sub_title', 'res_id', 'longtext')
# 表格search栏
search_fields = ('id', 'title')
# 过滤字段
list_filter = ('id', 'title')
admin.site.register(Media, MediaAdmin)
上面很多需要根据自己机器不断适配,包括mysql,apache,python依赖的安装,都要根据自己机器做安装。