Django学习笔记(6)---多应用、多数据库

原创
2013/02/12 22:44
阅读数 6K

       前一段在学习过程中,想的都比较简单,所以就只有一个应用一个数据库,但是当写的东西多了就发觉不同功能应该由不同应用来处理,不同应用可以使用单独使用自己的数据库,这样比较利于网站的扩展。原谅我,比较懒,所以废话就少说吧。

首先,假定项目名为test,有两个应用,user用于管理用户,essay用于管理文章。


python manage.py startapp userApp
python manage.py startapp essayApp
#userApp的models.py中
from django.db import models
class User(models.Model):
    name = models.CharField(max_length=30)
#essayApp中的models.py中
from django.db import models
from userApp.models import User
class Essay(models.Model):
    owner = models.ForeignKey(User,related_name="essay_owner")
    content = models.TextField()

在settings.py中为两个应用注册

INSTALLED_APPS = (
    #原来系统默认存在的我就略去不说了……
    'userApp',
    'essayApp',
    )

添加将要使用的数据库

DATABASES = {
    #之所以这里仍然保留default数据库,是因为如果要使用Django的Auth应用或者Admin应用
    #我希望它默认将数据存放在default.db中,而不与其他数据搞混,当然也可以额外指定,后边会说
     'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': 'db/default.db',
        'USER': '',
        'PASSWORD': '',
        'HOST': '',
        'PORT': '',
    },
    
    #提供给userApp使用
     'userdb': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': 'db/user.db',
        'USER': '',
        'PASSWORD': '',
        'HOST': '',
        'PORT': '',
    },

    #提供给essayApp使用
    'essaydb': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': 'db/essay.db',
        'USER': '',
        'PASSWORD': '',
        'HOST': '',
        'PORT': '',
    },
}

       就目前工作来说,还没完成,如果执行python manage.py syncdb 则会看到userApp_User和essayApp_Essay两张表都建在了default.db中,因为我们虽然添加了两个数据库配置,但是还没指定哪一个应用使用哪一个数据库,因此都使用了默认数据库配置 ‘default’

新建一个dbsetings.py

class appdb(object):

    def db_for_read(self, model, **hints):
        #该方法定义读取时从哪一个数据库读取
        return self.__app_router(model)

    def db_for_write(self, model, **hints):
        #该方法定义写入时从哪一个数据库读取,如果读写分离,可再额外配置
        return self.__app_router(model)

    def allow_relation(self, obj1, obj2, **hints):
        #该方法用于判断传入的obj1和obj2是否允许关联,可用于多对多以及外键
        #同一个应用同一个数据库
        if obj1._meta.app_label == obj2._meta.app_label:
            return True
        #User和Essay是允许关联的
        elif obj1._meta.app_label in ('userApp','essayApp') and
        #接上一行  obj2._meta.app_label in ('userApp','essayApp'):
            return True


    def allow_syncdb(self, db, model):
        #该方法定义数据库是否能和名为db的数据库同步
        return self.__app_router(model) == db

   #添加一个私有方法用来判断模型属于哪个应用,并返回应该使用的数据库
    def __app_router(self, model):
        if model._meta.app_label == 'userApp':
            return 'userdb'
        elif model._meta.app_label == 'essayApp':
            return 'essaydb'
        else :
            return 'default'

在settings.py中添加数据库配置文件
DATABASE_ROUTERS = ['dbsettings.appdb']

至此,工作基本完毕。

但是要注意的是必须单独为每一个数据库同步,即

python manage.py syncdb #默认同步的数据库为'default'
python manage.py syncdb --database=userdb  #为userdb同步数据
python manage.py syncdb --database=essaydb #为essaydb同步数据

关于不同数据库之间多对多和外键的查询,我明天再更新!

昨天本以为实现了不同数据库之间多对多的查询,外键可以正常访问,多对多今天研究半天都没有成功,查询Django官方文档,发现明确写着

Django目前不提供外键或多对多的关系跨越多个数据库的支持。如果你使用路由器分割模型对不同的数据库,任何FOREIGNKEY和多对多关系的模型定义必须是单个数据库的内部。
然而,如果你使用SQLite或MySQL,MyISAM,没有强制引用完整性;作为结果,你可以'假'跨数据库外键。然而,这样的配置是不由Django官方支持。
原来我渣一般的爬文水平,以上引用是机械翻译过来的……

原文:

https://docs.djangoproject.com/en/1.4/topics/db/multi-db/

参看链接页面最底部


     不过跨数据库之间的多对多和外键可以由自己实现,要写SQL语句,比较麻烦,我也不是很擅长,暂时研究到这

      我还是研究出了一种方法,详情请看学习笔记(7)



   转载请注明出处,谢谢!

展开阅读全文
打赏
0
10 收藏
分享
加载中
Linktime博主
该评论暂时无法显示,详情咨询 QQ 群:912889742
该评论暂时无法显示,详情咨询 QQ 群:912889742
更多评论
打赏
2 评论
10 收藏
0
分享
返回顶部
顶部