Django 多数据库 + mysql + wsgi + apache

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/duxiangwushirenfei/article/details/53870007

前言

许久未见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依赖的安装,都要根据自己机器做安装。

猜你喜欢

转载自blog.csdn.net/duxiangwushirenfei/article/details/53870007
今日推荐