Django基础-Model数据库多表操作(一对多)

创建多表外键关联

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',
    }
}
    原文作者:数据库基础
    原文地址: https://my.oschina.net/zhaojunhui/blog/2049175
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞