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

相关文章

Java学习手册之Filter和Listener使用方法

《Java学习手册之Filter和Listener使用方法》:本文主要介绍Java学习手册之Filter和Listener使用方法的相关资料,Filter是一种拦截器,可以在请求到达Servl... 目录一、Filter(过滤器)1. Filter 的工作原理2. Filter 的配置与使用二、Listen

Pandas统计每行数据中的空值的方法示例

《Pandas统计每行数据中的空值的方法示例》处理缺失数据(NaN值)是一个非常常见的问题,本文主要介绍了Pandas统计每行数据中的空值的方法示例,具有一定的参考价值,感兴趣的可以了解一下... 目录什么是空值?为什么要统计空值?准备工作创建示例数据统计每行空值数量进一步分析www.chinasem.cn处

Python的time模块一些常用功能(各种与时间相关的函数)

《Python的time模块一些常用功能(各种与时间相关的函数)》Python的time模块提供了各种与时间相关的函数,包括获取当前时间、处理时间间隔、执行时间测量等,:本文主要介绍Python的... 目录1. 获取当前时间2. 时间格式化3. 延时执行4. 时间戳运算5. 计算代码执行时间6. 转换为指

Python ZIP文件操作技巧详解

《PythonZIP文件操作技巧详解》在数据处理和系统开发中,ZIP文件操作是开发者必须掌握的核心技能,Python标准库提供的zipfile模块以简洁的API和跨平台特性,成为处理ZIP文件的首选... 目录一、ZIP文件操作基础三板斧1.1 创建压缩包1.2 解压操作1.3 文件遍历与信息获取二、进阶技

Windows 上如果忘记了 MySQL 密码 重置密码的两种方法

《Windows上如果忘记了MySQL密码重置密码的两种方法》:本文主要介绍Windows上如果忘记了MySQL密码重置密码的两种方法,本文通过两种方法结合实例代码给大家介绍的非常详细,感... 目录方法 1:以跳过权限验证模式启动 mysql 并重置密码方法 2:使用 my.ini 文件的临时配置在 Wi

Java中字符串转时间与时间转字符串的操作详解

《Java中字符串转时间与时间转字符串的操作详解》Java的java.time包提供了强大的日期和时间处理功能,通过DateTimeFormatter可以轻松地在日期时间对象和字符串之间进行转换,下面... 目录一、字符串转时间(一)使用预定义格式(二)自定义格式二、时间转字符串(一)使用预定义格式(二)自

MySQL重复数据处理的七种高效方法

《MySQL重复数据处理的七种高效方法》你是不是也曾遇到过这样的烦恼:明明系统测试时一切正常,上线后却频频出现重复数据,大批量导数据时,总有那么几条不听话的记录导致整个事务莫名回滚,今天,我就跟大家分... 目录1. 重复数据插入问题分析1.1 问题本质1.2 常见场景图2. 基础解决方案:使用异常捕获3.

最详细安装 PostgreSQL方法及常见问题解决

《最详细安装PostgreSQL方法及常见问题解决》:本文主要介绍最详细安装PostgreSQL方法及常见问题解决,介绍了在Windows系统上安装PostgreSQL及Linux系统上安装Po... 目录一、在 Windows 系统上安装 PostgreSQL1. 下载 PostgreSQL 安装包2.

Python正则表达式语法及re模块中的常用函数详解

《Python正则表达式语法及re模块中的常用函数详解》这篇文章主要给大家介绍了关于Python正则表达式语法及re模块中常用函数的相关资料,正则表达式是一种强大的字符串处理工具,可以用于匹配、切分、... 目录概念、作用和步骤语法re模块中的常用函数总结 概念、作用和步骤概念: 本身也是一个字符串,其中

SQL中redo log 刷⼊磁盘的常见方法

《SQL中redolog刷⼊磁盘的常见方法》本文主要介绍了SQL中redolog刷⼊磁盘的常见方法,将redolog刷入磁盘的方法确保了数据的持久性和一致性,下面就来具体介绍一下,感兴趣的可以了解... 目录Redo Log 刷入磁盘的方法Redo Log 刷入磁盘的过程代码示例(伪代码)在数据库系统中,r