创建多表外键关联
models.py
from 应用名 import models
class 表1(models.Model): #子表
id=models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID') #创建主键,自增长、设置主键、无序列号设置、详细名称为ID
字段1=models.CharField(max_length=20) #创建字符串字段,最大长度为20
字段2=models.IntegerField() #创建整型字段
字段3=models.ForeignKey("表2",on_delete=models.CASCADE,) #创建外键 【整型字段】,自动关联另外一张表主键,并设置级联删除
class 表2(models.Model): #主表
id=models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID') #创建主键,自增长、设置主键、无序列号设置、详细名称为ID
字段1=models.CharField(max_length=20) #创建字符串字段,最大长度为20
注:外键关联后,外键关联字段3名称在数据库中自动添加后缀_id,即变为 【字段3_id】
setting.py
INSTALLED_APPS = [应用名]
创建生成表
python manage.py makemigrations 应用名
python manage.py migrate
表数据操作
增加
在views.py中添加视图函数,要提前引用视图models类
from 应用名.models import 类名 #引入视图数据库models类
方法一:主表id形式赋值添加
注:需要在字段3,即外键字段中后加_id,和数据库保持一致
def 函数名(request):
表类名.objects.create(字段1="值1", 字段2="值2", 字段3_id=表2的id)
return 返回值
方法二:主表查找字段值添加
def 函数名(request):
数据对象=表类名.objects.filter(搜索的字段="搜索的值")[0] #根据字段搜索值,拿到值对象
表类名.objects.create(字段1="值1", 字段2="值2", 字段3=值对象) #对象赋值并非直接操作数据库
return 返回值
查询
正向查询
查询主表特定值,包含的所有子表值
方法一:获取主表对象当做子表查询条件
def 查询函数名(request): #查询数据函数
Env_Obj = 主表.objects.filter(Name="森林")[0] #获得主表符合条件对象
set=子表.objects.filter(外键字段名=Env_Obj).values("匹配字段1","匹配字段2") #在子表中搜索(主表获得对象作为条件)查询
return HttpResponse(set)
方法二:获取主表匹配项外键id,套用在子表中查询
def 查询函数名(request): #查询数据函数
set=子表.objects.filter(外键字段名__匹配字段名="字段值").values("匹配字段1","匹配字段2") #使用双下划线,在子表中搜索(主表特定值的id)
return HttpResponse(set)
反向查询
使用values双下划线,在子表中搜索特定值,取特定id显示主表该id对应值
def 查询函数名(request): #反向查询-查询数据函数
set = 子表.objects.filter(字段名="值").values("Link__匹配字段名") #使用values双下划线,在子表中搜索特定值,取特定id显示主表该id对应值
return HttpResponse(set)
一对多查询示例
models.py
# -*- coding:utf8 -*-
from django.db import models
########################################## 创建表 #########################################
class Env_Table(models.Model): #主表-环境表
id = models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID') # 创建主键,自增长、设置主键、无序列号设置、详细名称为ID
Name = models.CharField(max_length=20) #创建字符串字段,最大长度为20
class Animal_Table(models.Model): #子表-动物表
id=models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID') #创建主键,自增长、设置主键、无序列号设置、详细名称为ID
Type=models.CharField(max_length=20) #创建字符串字段,最大长度为20
Name=models.CharField(max_length=20) #创建字符串字段,最大长度为20
Link=models.ForeignKey("Env_Table",on_delete=models.CASCADE,) #创建外键 【整型字段】,自动关联另外一张表主键,并设置级联删除
#外键创建表在数据库默认 Django 会加后缀_id 表名称变更为 Link_id
views.py
# -*- coding:utf8 -*-
from django.shortcuts import render,HttpResponse
import datetime
from APP.models import Animal_Table
from APP.models import Env_Table
def Index(request): #网站默认首页
return render(request,"index.html",locals())
def Add_Env(request): # 添加主表函数
Env_Table.objects.create(Name="森林")
Env_Table.objects.create(Name="海里")
return HttpResponse("添加成功")
def Add_Animal(request): #添加子表函数
# 表中添加数据,外键连接字段需要在后缀添加 _id ,以数据库显示字段名为准
Animal_Table.objects.create(Type="食肉动物", Name="老虎", Link_id="1")
Animal_Table.objects.create(Type="食草动物", Name="兔子", Link_id="1")
Animal_Table.objects.create(Type="食草动物", Name="乌龟", Link_id="2")
Animal_Table.objects.create(Type="食肉动物", Name="鳄鱼", Link_id="2")
return HttpResponse("添加成功")
#方法一:获取主表对象当做子表查询条件-基于对象
# def Sel_data_z(request): #查询数据函数
# Env_Obj = Env_Table.objects.filter(Name="森林")[0] #获得主表符合条件对象
# set=Animal_Table.objects.filter(Link=Env_Obj).values("Type","Name") #在子表中搜索(主表获得对象作为条件)查询
# return HttpResponse(set)
#方法二:基于filte values 双下划线
def Sel_data_z(request): #正向查询-查询数据函数
#查询所有在“森林”里的动物
set=Animal_Table.objects.filter(Link__Name="森林").values("Type","Name") #使用双下划线,在子表中搜索主表特定值的id,显示子表该id的对应值
return HttpResponse(set)
def Sel_data_f(request): #反向查询-查询数据函数
# 查询动物在哪个环境
set = Animal_Table.objects.filter(Name="兔子").values("Link__Name") #使用values双下划线,在子表中搜索特定值,取特定id显示主表该id对应值
return HttpResponse(set)
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div>
<a href="/add_Anl/">一对多添加动物</a>
<a href="/add_Env/">添加环境</a>
<a href="/select_z/">正向查询数据</a>
<a href="/select_f/">反向查询数据</a>
</div>
</body>
</html>
urls.py
# coding=utf8
from django.contrib import admin
from django.urls import path,re_path
from APP import views
urlpatterns = [
path('admin/', admin.site.urls),
re_path('^$',views.Index),
path('add_Env/', views.Add_Env), # 添加主表
path('add_Anl/', views.Add_Animal), # 添加子表
path('select_z/', views.Sel_data_z), # 正向查询
path('select_f/', views.Sel_data_f), # 反向查询
]
__init__.py
import pymysql
pymysql.install_as_MySQLdb()
settings.py
INSTALLED_APPS
'APP',
TEMPLATES
'DIRS': [os.path.join(BASE_DIR, 'APP/templates')],
DATABASES
{
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'mydata',
'USER': 'mydata',
'PASSWORD': 'Abc123',
'HOST': '192.168.88.80',
'POST': '3306',
}
}