django - Models
本篇说明 django 使用资料库的方式
以及应用面会使用到的多资料库设置
本篇没有说明关联表的操作方式,后续系列会在深入研究
1.创建模型
# app(testSetting) > models.pyfrom django.db import models# 以下为一个一对多的关係,一个问题可以有很多个答案# 问题class Question(models.Model): question_text = models.CharField(max_length=200) pub_date = models.DateTimeField('date published') class Meta: db_table = 'question' # 指定资料库名称,否则预设为appName + 表名称 > ex: testSetting_question# 答案class Choice(models.Model): question = models.ForeignKey(Question, on_delete=models.CASCADE) choice_text = models.CharField(max_length=200) votes = models.IntegerField(default=0) class Meta: db_table = 'choice' # 资料库名称
2.同步资料库
从无到有,Table 尚未创建,则由django命令创建Table (延续2-1、2-2)Table已经存在,则利用命令快速创建代码 (可直接跳至3)基本上会遇到两种情况
2-1.注册App models的更动
于 CMD 视窗执行
py manage.py makemigrations
于各个App内的
migrations资料夹
会出现该次更新的内容
注意!!! 目前执行到这还尚未被资料库应用,所以在资料库中并不会看见资料表本次新增的内容
0001_initial.py
,主要为创建资料表内容的代码
2-2.实际连动资料库
于 CMD 视窗执行
python manage.py migrate testSetting
执行成功后于DB即可看到建置资料表,使用此命令,资料表名称会预设为appName + tableName,如下
3.实际操作
# views.py# 新增def addApi(request): q = Question(question_text="脸有什么器官?", pub_date=timezone.now()) q.save() # save(commit)才会实际执行 rep = { 'msg': 'add一笔资料' } return JsonResponse(rep)# 取得def getApi(request): data = Question.objects.all() # 取全部 # data = Question.objects.get() # 只取一笔 # data = Question.objects.filter(question_text = '条件') # 过滤条件 # 通常在使用上我会转为阵列字典形式,在使用以及回传json转换上都比较方便 rep = { 'msg': list(data.values()) } return JsonResponse(rep)# 修改def updateApi(request): data = Question.objects.filter(question_text="脸有什么器官?") # 取得需要修改的资料 data.update(question_text = '身体有什么器官?') rep = { 'msg': '修改一笔资料' } return JsonResponse(rep)# 删除def deleteApi(request): data = Question.objects.filter(question_text="身体有什么器官?") # 取得需要删除的资料 data.delete() rep = { 'msg': '删除一笔资料' } return JsonResponse(rep)
# 路由定义from django.urls import pathfrom . import viewsurlpatterns = [ path('firstApi', views.firstApi, name = 'firstApi'), path('addApi', views.addApi, name = 'addApi'), path('getApi', views.getApi, name = 'getApi'), path('updateApi', views.updateApi, name = 'updateApi'), path('deleteApi', views.deleteApi, name = 'deleteApi')]
4.多资料库使用
路由设置
基本上一个资料库要拥有所有东西是不太可能的,
有时候可能是因为部门、资料量、分类等等因素。
# 这边要新增一只档案# 于专案目录下新增 database_router.py# 内容大致上就是将增修改查指定的资料库配对到我们所需的位置from django.conf import settingsDATABASE_MAPPING = settings.DATABASE_APPS_MAPPINGclass DatabaseAppsRouter(object): """ A router to control all database operations on models for different databases. In case an app is not set in settings.DATABASE_APPS_MAPPING, the router will fallback to the `default` database. Settings example: DATABASE_APPS_MAPPING = {'app1': 'db1', 'app2': 'db2'} """ def db_for_read(self, model, **hints): """"Point all read operations to the specific database.""" if model._meta.app_label in DATABASE_MAPPING: return DATABASE_MAPPING[model._meta.app_label] return None def db_for_write(self, model, **hints): """Point all write operations to the specific database.""" if model._meta.app_label in DATABASE_MAPPING: return DATABASE_MAPPING[model._meta.app_label] return None def allow_relation(self, obj1, obj2, **hints): """Allow any relation between apps that use the same database.""" db_obj1 = DATABASE_MAPPING.get(obj1._meta.app_label) db_obj2 = DATABASE_MAPPING.get(obj2._meta.app_label) if db_obj1 and db_obj2: if db_obj1 == db_obj2: return True else: return False return None def allow_syncdb(self, db, model): """Make sure that apps only appear in the related database.""" if db in DATABASE_MAPPING.values(): return DATABASE_MAPPING.get(model._meta.app_label) == db elif model._meta.app_label in DATABASE_MAPPING: return False 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 db in DATABASE_MAPPING.values(): return DATABASE_MAPPING.get(app_label) == db elif app_label in DATABASE_MAPPING: return False return None
# project settings# 指定路由 > 为刚刚设置的档案# DATABASE_ROUTERS = ['专案名称.档案名称.功能名称']DATABASE_ROUTERS = ['djangoAPI.database_router.DatabaseAppsRouter']# 接下来就是设定的部份,预先会定义一个default,当没指定时就使用该DB# 其余部份就看使用的资料库引擎及定义名称、帐号、密码等等DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), }, 'db2': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BASE_DIR, 'db2.sqlite3'), }}# 路由配对DATABASE_APPS_MAPPING = { 'db2': 'db2'}
如此一来就设定好路由了,但注意该部份因为设置了路由,
所以各个部份都需要指定database给django,否则会出现一些错误
例如刚刚上述有提到的python manage.py migrate --database=dbName
这部份就需要指定资料库名称
详细了解可以看官方文档
模型定义
from django.db import models# 问题class Question(models.Model): question_text = models.CharField(max_length=200) pub_date = models.DateTimeField('date published') class Meta: app_label = 'db2' # setting DATABASE_APPS_MAPPING 配对名称 db_table = 'db2_question'
路由设置
# app.urlsfrom django.urls import pathfrom . import viewsurlpatterns = [ path('get_Db2_Api', views.get_Db2_Api, name = 'get_Db2_Api')]
实际使用与单个DB相同
以上就完成了实际应用会出现的多资料库的应用,在增修改查的使用上与酖个资料库相同,只要在模型中的Meta中设置完成就没问题了。