八.常用查询及关系的实现(二) 2021-03-08

八.常用查询及关系的实现(二)

1.示例:一对多 学生与学院

1.1结构设计

通过的外键联系起来两表

1.2建立模型

1.建立学生信息表与学院信息表模型

from django.db import models

# Create your models here.
'''
继承自模型类models
模型类和数据库表的关系
属性和表的字段的对应关系

'''

class Department(models.Model):
    #学院类
    d_id = models.AutoField(primary_key=True) # 设置主键以后,不会再自增长了
    d_name = models.CharField(max_length=20)

    class Meta:
        db_table = 'department'    # 给一个表名

    def __str__(self):
        return self.d_name

class Student(models.Model):
    s_id = models.AutoField(primary_key=True)
    s_name = models.CharField(max_length=30)
    #ForeignKey在定义时设置   连接的表名 ,related_name 参数来覆盖foo_set 的名称.
    department = models.ForeignKey('Department',on_delete=models.CASCADE)

    class Meta:
        db_table = 'student'

    def _str_(self):
        return self.s_name
        #     'Srudent<s_id = %s , s_name=%s>'%(
        #     self.s_id,self.s_name
        # )

注意:如果模型I有一个ForeignKey,那么该ForeignKey 所指的模型II实例可以通过一个管理器回前面有ForeignKey的模型I的所有实例。默认情况下,这个管理器的名字为foo_set,其中foo 是源模型的小写名称在定义时设置related_name 参数来覆盖foo_set 的名称.

1.3 将模型映射到数据库

1.首先执行以下命令,要创建映射文件

python  manage.py   makemigrations

命令后面可以跟app名称,表示指定对某个app的模型进行映射,没写所有的app都执行.

2.执行以下命令,将映射文件中的映射数据提交到数据库中

python  manage.py   migrate

3.进入mysql 查看映射的数据库表

  • mysql -uroot  -pqwe123             进入mysql
  • show  databases;                    查看所有的数据库
  • use look;                                 使用数据库
  • show tables                           查看数据库

打开数据我们能看到创建的以app名_模型名的数据表,而其他的一些表格是django自动生成的.

注意:如果要删除表,那么可以去django模型中注释掉模型类,然后执行映射的命令,不要手动在命令行里面去删除.

在执行前,保证我们创建模型的APP是已经注册过的APP


注意:在运行之前一定要将PyCharm的程序上传到虚拟机,不然会报一下错误

pymysql.err.OperationalError: (1046, 'No database selected')

django.db.utils.OperationalError: (1046, 'No database selected')

执行过程:

  • workon                     查看虚拟环境
  • workon   name         运行虚拟环境
  • ls                              查看目录下的文件
  • cd 项目文件              进入文件
  • python manage.py makemigrations        创建映射文件
  • python manage.py migrate                     映射文件中的映射数据提交到数据库中
  • show tables               查看建立的表   

查看映射的表

1.查看所有数据库

2.使用数据库,查看库里的所有表

3.查看学院表数据结构

4.查看学生表数据结构

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

1.4添加数据

1.在子应用的views中导入models.py文件,写显示函数

from django.shortcuts import render

from django.http import HttpResponse
from  .models import Department,Student        #导入建立的模型
# Create your views here.



def add_Department_Student(request):
    #向学院表与学生表添加信息
    #添加学院信息
    d1 = Department(d_id = 1 ,d_name = '文学院')
    d1.save()
    d2 = Department(d_id = 2, d_name = '计算机技术')
    d2.save()
    #添加学生信息
    #方法1 :.第一种方式就是跟之前的一样,用传参的方法添加,需要注意的是外键的值必须是关联表中已经存在的值.
    s1 = Student(s_id = 1 , s_name = '忘记',department_id = 2)
    s1.save()
    #方法2 :用的属性赋值的方式,因为我们在模型类有定义了一个department的属性,而这个属性的对象的类型必须是department表的类实例对象
    s2 = Student(s_id = 2 ,s_name = '坚强')
    s2.department = d2
    s2.save()

    s3 = Student(s_id = 3 , s_name = '嘿你好',department_id = 1)
    s3.save()
    return  HttpResponse('插入成功')

2.设置子路由的url

from django.urls import path,re_path
from  .import views

urlpatterns = [
    #添加学生与学院信息
    path('add_Department_Student',views.add_Department_Student ,name = 'add_Department_Student'),
]

3.运行结果:

4.在虚拟机的Mysql中查询新建的表

1.5表关联对象的访问

1.在子应用的views中导入models.py文件,写显示函数

from django.shortcuts import render

from django.http import HttpResponse
from  .models import User,BookInfo,Department,Student        #导入建立的模型
# Create your views here.



def test_Info_Department_Student(request):
    s1 = Student.objects.get(s_id=1)  #给学生一个实例对象
    d1 = Department.objects.get(d_id=1) #给学院一个实例对象

    print(d1.student_set) #反向的时候是一种管理器,里面包含了方法
    print(d1.student_set.all()) #.all 拿到该学院学生的所有数据

    #add()方法     修改数据,无序用seve()保存,自动保存,适用于   一对多,多对多
    d1.student_set.add(s1)    #将学生id为1的学生换到学院id为1
    # creat()方法   新建数据   一对多,多对多
    d1.student_set.create(s_name = '张画')  #给学院id为1添加学生

    return HttpResponse('访问成功')

2.设置子路由的url

from django.urls import path,re_path
from  .import views

urlpatterns = [
 
    #访问学生与学员信息
    path('test_Info_Department_Student',views.test_Info_Department_Student ,name = 'test_Info_Department_Student'),
]

3.运行结果:

4.在虚拟机的Mysql中表前后对比

 

 

 

 

 

 

 

 

 

1.6处理关联对象方法

用法同上1.5 (下面是在终端实现的,不过方法是一样的)

1.  add(obj1, obj2, ...)  添加的已经存在数据库的数据

添加一指定的模型对象到关联的对象集中。

1.d1.student的管理器有add的方法.

2.例子中的s2能添加成功是因为设置了student表中department字段允许为空了.

2.create(**kwargs)  添加不存在的数据 ,将数据直接存入数据库

创建一个新的对象,将它保存并放在关联的对象集返回新创建的对象

 

3.remove(obj1, obj2, ...)   从关联的对象集中删除指定的模型对象。

删除的是关系表中的数据的对象集中。

因为我们有修改student表中的department_id字段允许为空,所以当删除的时候这个字段值为NULL.

4.clear()    从关联的对象集中删除所有的对象

 注意:注意对于所有类型的关联字段,add()、create()、remove()和clear()都会马上更新数据库。换句话说,在关联的任何一端,都不需要再调用save()方法。 

2.多对多查询

Django 提供一种强大而又直观的方式来“处理”查询中的关联关系,它在后台自动帮你处理JOIN。 若要跨越关联关系,只需使用关联的模型字段的名称,并使用双下划线分隔,直至你想要的字段:

# 查询学院名字为‘计算机学院’的学生的信息 
Student.objects.filter(department__d_name='计算机学院')

它还可以反向工作。若要引用一个“反向”的关系,只需要使用该模型的小写的名称。

#查询学生名字中包含 '小' 的学生的学院信息
Department.objects.filter(student__s_name__contains='小')
# 查询学号为1的学生所有的课程
Course.objects.filter(student__s_id=1)
# 查询报了课程1的所有的学生
Student.objects.filter(course__c_id=1)
# 查询报了'python'课程的的学生的所属学院的信息
Department.objects.filter(student__course__c_name='python')

关于多对多表查询的详细信息:查看Django(多表查询操作) - SmllNine - 博客园 (cnblogs.com) 

3.查询方法补充

3.1 聚合查询

聚合查询:aggregate()是QuerySet 的一个终止子句,它返回一个包含一些键值对的字典

键的名称是聚合值的标识符,值是计算出来的聚合值。键的名称是按照字段和聚合函数的名称自动生成出来的。如果你想要为聚合值指定一个名称,可以向聚合子句提供它。

3.2分组查询

annotate():为QuerySet中每一个对象都生成一个独立的汇总值。

 是对分组完之后的结果进行的聚合

3.3 F查询

Django 提供 F() 来做这样的比较。F() 的实例可以在查询中引用字段,来比较同一个 model 实例中两个不同字段的值

3.4 Q查询

Q查询:  如果你需要执行更复杂的查询(例如OR语句),你可以使用Q对象。

Q对象可以使用&(and)、|(or)操作符组合起来

使用~(not)操作符在Q对象前表示取反

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值