创建多表外键关联

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

Title

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',

}

}

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐