django-一对一、一对多、多对多操作、常用方法

2024-08-31 22:32

本文主要是介绍django-一对一、一对多、多对多操作、常用方法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

      • 准备表
      • 一对一操作
      • 一对多操作
      • 多对多操作
      • 常用方法
      • 了不起的双下划线

准备表

创建如下几张表

from django.shortcuts import HttpResponse, render, redirect
from django.db import modelsclass Class(models.Model):id = models.AutoField(primary_key=True)cname = models.CharField(max_length=32)cdata = models.DateField()def __str__(self):return "%s" % [self.__class__, self.cname]class Student(models.Model):id = models.AutoField(primary_key=True)sname = models.CharField(max_length=32)# 一对多# cid = models.ForeignKey(to="Class",to_field="id",related_name="student")cid = models.ForeignKey(to="Class", to_field="id")# 一对一detail = models.OneToOneField("StudentDetail", to_field="id")# 等同于如下的代码# detail = models.ForeignKey(to="StudentDetail",to_field="id",unique=True)def __str__(self):return "%s" % [self.sname]# #建立多对多  第一种方法
# class Teacher(models.Model):
#     id = models.AutoField(primary_key=True)
#     tname = models.CharField(max_length=32)
#
#
# class Teacher2Class(models.Model):m
#     id = models.AutoField(primary_key=True)
#     tid = models.ForeignKey(to="Teacher",to_field="id")
#     cid = models.ForeignKey(to="Class",to_field="id")
#
#     class Meta:
#         unique_together = ("tid","cid")# 建立多对多  第二种方法
class Teacher(models.Model):id = models.AutoField(primary_key=True)tname = models.CharField(max_length=32)cid = models.ManyToManyField(to="Class",name="teacher")# 建立多对多  第3种方法
# class Teacher(models.Model):
#     id = models.AutoField(primary_key=True)
#     tname = models.CharField(max_length=32)
#     cid_tid = models.ManyToManyField(to="Class",
#                                      through="Teacher2Class",
#                                      through_fields=("tid", "cid"))
#
# class Teacher2Class(models.Model):
#     id = models.AutoField(primary_key=True)
#     tid = models.ForeignKey(to="Teacher", to_field="id")
#     cid = models.ForeignKey(to="Class", to_field="id")
#
#     class Meta:
#         unique_together = ("tid", "cid")class StudentDetail(models.Model):id = models.AutoField(primary_key=True)height = models.PositiveIntegerField()email = models.EmailField()memo = models.CharField(max_length=128)

需要注意的如下:

  # 一对多# cid = models.ForeignKey(to="Class",to_field="id",related_name="student")cid = models.ForeignKey(to="Class", to_field="id")# 一对一detail = models.OneToOneField("StudentDetail", to_field="id")# 等同于如下的代码# detail = models.ForeignKey(to="StudentDetail",to_field="id",unique=True)

来看下几个表的表名、字段名
app01_class班级表:
这里写图片描述

app01_student学生表:
这里写图片描述

app01_studentdetail学生信息表:
这里写图片描述

app01_class老师表:
这里写图片描述

app01_teacher2class班级老师表:
这里写图片描述

以上的app01_teacher2class表是通过第3种方法创建的,我们来看下第一种、第二方法创建的表名、字段名是怎样的?

通过方法1 创建班级-老师对应表如下:
这里写图片描述

通过方法2 创建班级-老师对应表如下:

这里写图片描述

一对一操作

正向查询(由学生信息表查询学生详情表)

stu = models.Student.objects.first()
stu.detail.email
'1@qq'

反向查询(由学生详情表反向查询学生信息表)

detail = models.StudentDetail.objects.get(id=1)
detail.student.sname
'小一

一对多操作

正向查询(由学生表查询班级表)

from app01 import models
stu = models.Student.objects.first()
stu.cid_id
1
stu.cid.cname
'全栈1期'

反向查询(由班级表查询学生表)

cls = models.Class.objects.first()
cls.student_set.all()
<QuerySet [<Student: ['小一']>, <Student: ['小二']>]>

注意:

如果不在外键的字段中设置related_name的话,默认就用表名_set。
如果设置了related_name=”students”,反向查询时可直接使用students进行反向查询。

cls.students.all() 

多对多操作

正向查询(由老师表查询班级表)

from app01 import models
tea = models.Teacher.objects.first()
tea.cid_tid
<django.db.models.fields.related_descriptors.create_forward_many_to_many_manager.<locals>.ManyRelatedManager object at 0x05C110F0>tea.cid_tid.all()
<QuerySet [<Class: [<class 'app01.models.Class'>, '全栈1期']>, <Class: [<class 'app01.models.Class'>, '全栈2期']>]>first = tea.cid_tid.first()
first
<Class: [<class 'app01.models.Class'>, '全栈1期']>first.cname
'全栈1期'first.student_set
<django.db.models.fields.related_descriptors.create_reverse_many_to_one_manager.<locals>.RelatedManager object at 0x03283870>first.student_set.all()
<QuerySet [<Student: ['小一']>, <Student: ['小二']>]>

反向查询(由班级表反向查询老师表)

cls = models.Class.objects.first()
cls.student_set
<django.db.models.fields.related_descriptors.create_reverse_many_to_one_manager.<locals>.RelatedManager object at 0x03283070>cls.teacher_set
<django.db.models.fields.related_descriptors.create_forward_many_to_many_manager.<locals>.ManyRelatedManager object at 0x03224710>cls.teacher_set.all()
<QuerySet [<Teacher: Teacher object>, <Teacher: Teacher object>]>cls.teacher_set.all().first()
<Teacher: Teacher object>cls.teacher_set.all().first().cid_tid
<django.db.models.fields.related_descriptors.create_forward_many_to_many_manager.<locals>.ManyRelatedManager object at 0x032A2790>cls.teacher_set.all().first().tname
'王老师'

常用方法

create()

from app01 import models
import datetime
teacher = models.Teacher.objects.get(id=1)
teacher.cid.create(cname="linux2",cdata=datetime.datetime.now())
<Class: [<class 'app01.models.Class'>, 'linux2']>

多对对

cls = models.Class.objects.get(id=1)
cls.teacher_set.create(tname="egon")
<Teacher: Teacher object>
import datetime
cls = models.Class.objects.first()
cls.student_set.create(sname="王七",detail_id=4)
stu = models.Student.objects.create(sname="wyf",detail_id=5,cid_id=2)

以下方式对多对多不行!!
这里写图片描述

add()

from app01 import models
import datetime
cls = models.Class.objects.all()
models.Teacher.objects.first().cid.add(*cls)

set\remove\clear

tea = models.Teacher.objects.first()
tea.cid.set([4,3])
tea.cid.remove(3)
tea.cid.clear()

了不起的双下划线

这里写图片描述

models.Class.objects.filter(student__sname__contains="d")
<QuerySet [<Class: [<class 'app01.models.Class'>, 'python']>, <Class: [<class 'app01.models.Class'>, 'sfsdf']>]>
models.Class.objects.values("cname")
<QuerySet [{'cname': 'linux'}, {'cname': 'python'}, {'cname': 'sfsdf'}]>models.Class.objects.values("cname","student__sname")
<QuerySet [{'cname': 'linux', 'student__sname': 'wyf'}, {'cname': 'python', 'student__sname': 'wfdsd'}, {'cname': 'sfsdf', 'student__sname': 'fdgerter'}]>

以下方法不可行!!

models.Class.objects.first().values("cname","student__sname")
Traceback (most recent call last):File "<input>", line 1, in <module>
AttributeError: 'Class' object has no attribute 'values'
models.Class.objects.all().values("cname","student__detail__email")<QuerySet [{'cname': 'linux', 'student__detail__email': '1@qq'}, {'cname': 'python', 'student__detail__email': '2@werwe'}, {'cname': 'sfsdf', 'student__detail__email': '4@fds'}, {'cname': 'linux', 'student__detail__email': '2@werw'}]>

这篇关于django-一对一、一对多、多对多操作、常用方法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1125178

相关文章

MySQL查询JSON数组字段包含特定字符串的方法

《MySQL查询JSON数组字段包含特定字符串的方法》在MySQL数据库中,当某个字段存储的是JSON数组,需要查询数组中包含特定字符串的记录时传统的LIKE语句无法直接使用,下面小编就为大家介绍两种... 目录问题背景解决方案对比1. 精确匹配方案(推荐)2. 模糊匹配方案参数化查询示例使用场景建议性能优

关于集合与数组转换实现方法

《关于集合与数组转换实现方法》:本文主要介绍关于集合与数组转换实现方法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、Arrays.asList()1.1、方法作用1.2、内部实现1.3、修改元素的影响1.4、注意事项2、list.toArray()2.1、方

Python中注释使用方法举例详解

《Python中注释使用方法举例详解》在Python编程语言中注释是必不可少的一部分,它有助于提高代码的可读性和维护性,:本文主要介绍Python中注释使用方法的相关资料,需要的朋友可以参考下... 目录一、前言二、什么是注释?示例:三、单行注释语法:以 China编程# 开头,后面的内容为注释内容示例:示例:四

mysql表操作与查询功能详解

《mysql表操作与查询功能详解》本文系统讲解MySQL表操作与查询,涵盖创建、修改、复制表语法,基本查询结构及WHERE、GROUPBY等子句,本文结合实例代码给大家介绍的非常详细,感兴趣的朋友跟随... 目录01.表的操作1.1表操作概览1.2创建表1.3修改表1.4复制表02.基本查询操作2.1 SE

一文详解Git中分支本地和远程删除的方法

《一文详解Git中分支本地和远程删除的方法》在使用Git进行版本控制的过程中,我们会创建多个分支来进行不同功能的开发,这就容易涉及到如何正确地删除本地分支和远程分支,下面我们就来看看相关的实现方法吧... 目录技术背景实现步骤删除本地分支删除远程www.chinasem.cn分支同步删除信息到其他机器示例步骤

python常用的正则表达式及作用

《python常用的正则表达式及作用》正则表达式是处理字符串的强大工具,Python通过re模块提供正则表达式支持,本文给大家介绍python常用的正则表达式及作用详解,感兴趣的朋友跟随小编一起看看吧... 目录python常用正则表达式及作用基本匹配模式常用正则表达式示例常用量词边界匹配分组和捕获常用re

c++中的set容器介绍及操作大全

《c++中的set容器介绍及操作大全》:本文主要介绍c++中的set容器介绍及操作大全,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录​​一、核心特性​​️ ​​二、基本操作​​​​1. 初始化与赋值​​​​2. 增删查操作​​​​3. 遍历方

在Golang中实现定时任务的几种高效方法

《在Golang中实现定时任务的几种高效方法》本文将详细介绍在Golang中实现定时任务的几种高效方法,包括time包中的Ticker和Timer、第三方库cron的使用,以及基于channel和go... 目录背景介绍目的和范围预期读者文档结构概述术语表核心概念与联系故事引入核心概念解释核心概念之间的关系

MySQL追踪数据库表更新操作来源的全面指南

《MySQL追踪数据库表更新操作来源的全面指南》本文将以一个具体问题为例,如何监测哪个IP来源对数据库表statistics_test进行了UPDATE操作,文内探讨了多种方法,并提供了详细的代码... 目录引言1. 为什么需要监控数据库更新操作2. 方法1:启用数据库审计日志(1)mysql/mariad

在Linux终端中统计非二进制文件行数的实现方法

《在Linux终端中统计非二进制文件行数的实现方法》在Linux系统中,有时需要统计非二进制文件(如CSV、TXT文件)的行数,而不希望手动打开文件进行查看,例如,在处理大型日志文件、数据文件时,了解... 目录在linux终端中统计非二进制文件的行数技术背景实现步骤1. 使用wc命令2. 使用grep命令