Django模型层(附带test环境)

Django模型层(附带test环境)

目录

  • Django模型层(附带test环境)
    • 连接数据库
    • Django ORM
      • 在models.py中建表
      • 允许为空
      • 指定默认值
      • 数据库迁移命令
    • 开启测试环境
    • 建表语句补充(更改默认表名)
    • 数据的增加
      • 时间数据的时区
    • 多表数据的增加
        • 一对多
        • 多对多
    • 数据的删除
    • 修改数据
    • 查询数据
    • 查询所有数据
    • 去重查询
    • 排序查询
    • 统计
    • 剔除指定数据
    • 多表查询
      • 示例
        • 一对多:图书与出版社
        • 多对多:图书和作者
          • 方式【1】**推荐**
          • 方式【2】**不推荐**
    • 校验数据是否存在
    • 字段的筛选查询
    • 连表查询
      • 正向查询
      • 反向查询
    • 聚合函数(aggregate)
    • 分组查询
    • F与Q查询
      • F查询
      • Q查询
    • Django开启事务
    • choices参数

连接数据库

这是Django默认的数据库

DATABASES = {'default': {'ENGINE': 'django.db.backends.sqlite3','NAME': BASE_DIR / 'db.sqlite3',}
}

修改为我们需要的配置

DATABASES = {'default': {'ENGINE': 'django.db.backends.mysql','NAME': 'mydj','USER': 'root','PASSWORD': '7997','HOST': '127.0.0.1','PORT': 3306,'CHARSET': 'utf8',}
}

django 默认使用mysqldb模块链接mysql

但是该模块的兼容性不好,需要手动修改为pymysql链接

在项目下的init或者任意的应用名下的init文件中书写一下代码

  • init.py
import pymysqlpymysql.install_as_MySQLdb()

Django ORM

在models.py中建表

id字段Django会自动帮忙创建

from django.db import models# Create your models here.
class User(models.Model):username = models.CharField(max_length=32)password = models.CharField(max_length=32)

允许为空

class MyModel(models.Model):name = models.CharField(max_length=50, null=True)  # 允许name字段为空

指定默认值

class MyModel(models.Model):age = models.IntegerField(default=18)  # 默认年龄为18岁

数据库迁移命令

  1. 创建操作记录

    • python manage.py makemigrations
      

      操作完后Django会自动在migrations目录下生成sql语句文件

      img

  2. 同步到数据库

    • python manage.py migrate
      

image-20240227221100284

等待表创建完毕

image-20240227221134422

这样就是成功执行建表语句了

删除字段只要在models中删除对应的字段行,然后重新makemigrations即可生成新的sql语句

开启测试环境

首先在app下找到tests.py文件并进入

image-20240304172704561

'MyDJ.settings'要换成自己的项目名,我的是MyDJ

import osfrom django.test import TestCaseif __name__ == '__main__':# 导入一句话 : 来自于 manage.py 中的第一句话os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'MyDJ.settings')import djangoimport datetime# 启动Djangodjango.setup()from app01 import models# 开始业务代码user = models.user.objects.create(username='张三',password='222')

image-20240304172608371

成功~

建表语句补充(更改默认表名)

class Book(models.Model):# 书名title = models.CharField(max_length=32)# 定价price = models.IntegerField()# 出版日期publish_date = models.DateTimeField(auto_now=True)# 绑定出版社外键publish = models.ForeignKey('Publish', on_delete=models.CASCADE, to_field='id', default=1)# 绑定图书表和作者表,用ManyToManyField自动创建第三张表author = models.ManyToManyField('Author')class Meta():# 不添加的话默认表名app01_bookdb_table = 'book'

数据的增加

data = models.user.objects.create(username="李四",password=929)
data = models.user(username="陈五",password=909)
data.save()

时间数据的时区

创建时间字段(如:DateTimeField())

中国时区需要将settings中部分设置修改为:

LANGUAGE_CODE = 'zh-hans'TIME_ZONE = 'Asia/Shanghai'

多表数据的增加

一对多

此时有一张作者表和作者详情表

作者详情表绑定这作者表的id

class Author(models.Model):# 作者名name = models.CharField(max_length=32, unique=True)# 年龄age = models.IntegerField()class Meta():db_table = 'author'class AuthorDetail(models.Model):# 作者电话phone = models.CharField(max_length=11)# 作者地址addr = models.CharField(max_length=132)# 作者名 绑定外键author_name = models.ForeignKey('Author', on_delete=models.CASCADE, to_field='id', default=1, null=True)class Meta():db_table = 'authordetail'

对外键关系表进行增加操作

import osfrom django.test import TestCase
import datetimeif __name__ == '__main__':os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'MyDJ.settings')import djangoimport datetimedjango.setup()from app01 import models# author_name内必须是一个Author实例对象,不能直接使用参数内容models.Author.objects.create(name='张三', age=11)detail_id = models.Author.objects.get(id=1)models.AuthorDetail.objects.create(phone='123', addr="北京", author_name=detail_id)
多对多

假设有一张图书表和作者表,两者由第三张表绑定外键关系

class Book(models.Model):# 书名title = models.CharField(max_length=32)# 定价price = models.IntegerField()# 出版日期publish_date = models.DateTimeField(auto_now=True)# 绑定图书表和作者表,用ManyToManyField自动创建第三张表author = models.ManyToManyField('Author')class Meta():# 不添加的话默认表名app01_bookdb_table = 'book'class Author(models.Model):# 作者名name = models.CharField(max_length=32, unique=True)# 年龄age = models.IntegerField()class Meta():db_table = 'author'
import osfrom django.test import TestCase
import datetimeif __name__ == '__main__':os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'MyDJ.settings')import djangoimport datetimedjango.setup()from app01 import models# 为作者和图书的多对多的第三张表添加信息author_obj = models.Author.objects.get(id=1)book_obj = models.Book.objects.get(id=1)book_obj.author.add(author_obj)# 删除外键关系'''author_obj = models.Author.objects.get(id=1)book_obj = models.Book.objects.get(id=1)book_obj.author.remove(author_obj)'''# 修改外键关系'''author_obj = models.Author.objects.get(id=2)book_obj = models.Book.objects.get(id=1)book_obj.author.set([author_obj])'''# 清空外键关系'''book_obj = models.Book.objects.get(id=1)book_obj.author.clear()'''

author_obj:获取作者表实例

book_obj:获取图书表实例

book_obj.author.add(author_obj):add内的参数是author表的实例

数据的删除

data = models.user.objects.filter(username="张三").delete()
data = models.user.objects.get(id=9)
data.delete()

修改数据

data = models.user.objects.get(id=10)
data.password=111
data.save()
data = models.user.objects.filter(id=10).update(username="张三")

查询数据

data = models.user.objects.filter(id=3)
print(data.values())
# get不能查询不存在的数据,否则会报错
data = models.user.objects.get(id=1)

查询所有数据

# 查询所有数据
data = models.user.objects.values()
# id=1的所有字段
data = models.user.objects.filter(id=1).values()
# 元组查询,结果只有值没有键
data = models.user.objects.values_list()
data = models.user.objects.filter(id=1).values_list()

去重查询

# 相同的username字段不会被多次查询
data = models.user.objects.values('username').distinct()
print(data)
data = models.user.objects.values('username','password').distinct()

排序查询

# 从小到大
data = models.user.objects.order_by('id').values('id')
# 从大到小
data = models.user.objects.order_by('-id').values('id')

统计

# 统计库中所有数据
data = models.user.objects.values().count()
# 库中名为admin的数量
data = models.user.objects.filter(username="admin").count()

剔除指定数据

# 排除id=1的数据
data = models.user.objects.values().exclude(id=1)

多表查询

假设有user、user2两个模型

# 一对多
data = models.user.objects.select_related('user2').all()
# 多对多
users = User.objects.prefetch_related('user2').all()

示例

创建book(书籍),Publish(出版社),Author(作者),AuthorDetail(作者详情)四个表

import datetimefrom django.db import modelsclass Book(models.Model):# 书名title = models.CharField(max_length=32)# 定价price = models.IntegerField()# 出版日期publish_date = models.DateTimeField(auto_now=datetime.datetime.now())class Publish(models.Model):# 出版社名name = models.CharField(max_length=32)# 出版社地址addr = models.CharField(max_length=132)# 出版社邮箱email = models.CharField(max_length=32)class Author(models.Model):# 作者名name = models.CharField(max_length=32)# 年龄age = models.IntegerField()class AuthorDetail(models.Model):# 作者电话phone = models.CharField(max_length=11)# 作者地址addr = models.CharField(max_length=132)
# 创建迁移文件
python manage.py makemigrations
python manage.py migrate
一对多:图书与出版社

一个出版社可以有多本图书,但是一本书只能有一个出版社

class Book(models.Model):# 书名title = models.CharField(max_length=32)# 定价price = models.IntegerField()# 出版日期publish_date = models.DateTimeField(auto_now=datetime.datetime.now())# 绑定出版社外键publish = models.ForeignKey('Publish',on_delete=models.CASCADE,to_field='id',default=1, null=True)

models.ForeignKey('Publish'):与Publish表关联

on_delete=models.CASCADE:指定外键关系(当图书信息被删除时出版社信息也会被删除)

to_field='id',default=1:绑定author表的id主键,并默认为1

多对多:图书和作者

一本书可以有多个作者,一个作者也可以创作多本书

方式【1】推荐

在Book类中使用ManyToManyField自动创建第三张表

# 绑定图书表和作者表,用ManyToManyField自动创建第三张表
author = models.ManyToManyField('Author')

image-20240308164602466

方式【2】不推荐

手动创建第三张表

class Book_Author(models.Model):book = models.ForeignKey('Book',on_delete=models.CASCADE())author = models.ForeignKey('Author',on_delete=models.CASCADE())

手动制定ManyToManyField参数:

through:绑定的第三张表

through_fields:绑定所需的字段

    author = models.ManyToManyField(to='Author',through='Book_Author',through_fields=('book','author'))

校验数据是否存在

data = models.user.objects.filter(id=1).exists()
print(data) # True/False

字段的筛选查询

条件运算

  • 大于gt
data = models.user.objects.filter(id__gt=5)
  • 小于lt
data = models.user.objects.filter(id__lt=5)
  • 大于等于gte
data = models.user.objects.filter(id__gte=5)
  • 小于等于lte
data = models.user.objects.filter(id__lte=5)
  • in
data = models.user.objects.filter(id__in=[1, 2, 3])
  • 两个条件之间range
# 顾头顾尾 因此返回id=1,2,3的数据
data = models.user.objects.filter(id__range=[1,3]).values()
  • 模糊查询contains(默认区分大小写)
data = models.user.objects.filter(username__contains='三').values()
  • 模糊查询取消大小写限制icontains
data = models.user.objects.filter(username__icontains='三').values()
  • 以指定字符开头/结尾startswith/endswitch
data = models.user.objects.filter(username__startswith='张').values()
  • 过滤指定时间区间time
# 过滤时间小于当前时间的数据
current_time = datetime.datetime.now()
data = models.user.objects.filter(up_time__lt=current_time).values()

连表查询

对于已经绑定了外键的字段,可以使用连表查询一次查询不同表中的数据

image-20240308205422776

image-20240308205433567

示例中有一个author表和authordetail表,authordetail的author_name_id字段绑定了author的id主键

正向查询

于是便可以通过获取author表中的示例然后.values('authordetail__phone')获取authordetail表中的phone字段,如下:

author_obj = models.Author.objects.filter(name='张三').values('authordetail__phone')
print(author_obj)

反向查询

当要使用没有绑定外键的字段来查询有外键字段的内容时:

author_obj = models.AuthorDetail.objects.filter(author_name__name='张三').values('author_name__name','phone')print(author_obj)

聚合函数(aggregate)

聚合函数需要在分组的情况下使用,并且需要导入Django中内置的聚合模块

from django.db.models import Avg, Sum, Max, Min, Countavg_price = models.Book.objects.aggregate(Avg('price'))
print(avg_price)  # 获取书的平均价格
sum_price = models.Book.objects.aggregate(Sum('price'))
print(sum_price)  # 获取书的总价
max_price = models.Book.objects.aggregate(Max('price'))
print(max_price)  # 获取最贵的书
min_price = models.Book.objects.aggregate(Min('price'))
print(min_price)  # 获取最便宜的书
count_price = models.Book.objects.aggregate(Count('price'))
print(count_price)  # 获取书的数量

分组查询

查询每本书有几个作者(作者绑定外键)

image-20240308222027689

作者

image-20240308222046680

绑定的外键表

image-20240308222115530

book_obj = models.Book.objects.annotate(a=Count("author")).values('a')
print(book_obj)
# <QuerySet [{'a': 2}, {'a': 1}, {'a': 1}]>

F与Q查询

首先要导入模块

from django.db.models import Count, F, Q, Value
from django.db.models.functions import Concat

F查询

将所有书的价格增加100

# 将所有书的价格增加100
book_obj = models.Book.objects.update(price=F('price')+100)

Q查询

image-20240308224351919

# 原语句
# book_obj = models.Book.objects.filter(price__gt=400,price__lt=700)
# Q语句
book_obj = models.Book.objects.filter(Q(price__gt=400),Q(price__lt=700)
print(book_obj.values('title'))
# <QuerySet [{'title': '水浒传'}]>

获取价格大于400或小于700的数据

book_obj = models.Book.objects.filter(Q(price__gt=400) or Q(price__lt=700))print(book_obj.values('title'))
book_obj = models.Book.objects.filter(Q(price__gt=400) | Q(price__lt=700))print(book_obj.values('title'))

or|的区别:

  • 使用 | 运算符时,两个条件都会被考虑,并返回满足任何一个条件的结果
  • 使用 or 运算符时,只有第一个条件会被返回,不会考虑第二个条件

Django开启事务

from django.db import transaction
try:# 开启事务with transaction.atomic():# 在事务开启前的保存点save_id = transaction.savepoint()# 这部分代码会在事务中执行models.Book.objects.create(title='三国演义',price=1000)transaction.savepoint_commit(save_id)
except Exception as e:# 出错后回滚到save_id开始的地方transaction.savepoint_rollback(save_id)

choices参数

gender_choice 是一个元组列表,用于定义 Author 模型中 gender 字段的选项

class Author(models.Model):gender_choice = ((0,'男'),(1,'女'),(2,'保密'))# 作者名name = models.CharField(max_length=32, unique=True)# 年龄age = models.IntegerField()# 性别gender = models.IntegerField(choices=gender_choice,default=2)
if __name__ == '__main__':os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'MyDJ.settings')import djangoimport datetimedjango.setup()from app01 import modelsfrom django.db import transactionauthor_obj = models.Author.objects.get(id=1)print(author_obj.gender)# 直接获取得到的是实际值:2print(author_obj.gender_choice)# 获取关联的choice元组:((0, '男'), (1, '女'), (2, '保密'))print(author_obj.get_gender_display())# 获取展示给用户的值:保密

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/733543.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

鸿蒙OpenHarmony HDF 驱动开发

目录 序一、概述二、HDF驱动框架三、驱动程序四、驱动配置坚持就有收获 序 最近忙于适配OpenHarmonyOS LiteOS-M 平台&#xff0c;已经成功实践适配平台GD32F407、STM32F407、STM32G474板卡&#xff0c;LiteOS适配已经算是有实际经验了。 但是&#xff0c;鸿蒙代码学习进度慢下…

【AcWing】蓝桥杯集训每日一题Day1|二分|差分|503.借教室(C++)

503. 借教室 503. 借教室 - AcWing题库难度&#xff1a;简单时/空限制&#xff1a;1s / 128MB总通过数&#xff1a;8052总尝试数&#xff1a;26311来源&#xff1a;NOIP2012提高组算法标签二分差分 题目内容 在大学期间&#xff0c;经常需要租借教室。 大到院系举办活动&…

基于机器学习的网络入侵检测二元分类模型构建与性能评估(NSL-KDD数据集)

简介 该项目是一个基于NSL-KDD数据集的网络入侵检测系统&#xff0c;主要采用机器学习方法对网络流量数据进行使用了多种机器学习模型&#xff0c;如逻辑回归、线性SVM、多项式核SVM、高斯核SVM、决策树、随机森林、朴素贝叶斯和K近邻算法训练二元分类&#xff08;正常/异常&a…

bug总结(1)--变量取错

a c t i v i t y [ ′ t a g n a m e ′ ] 应为 activity[tag_name]应为 activity[′tagn​ame′]应为couponActivitList[0][‘name’] .隐藏的bug&#xff0c;在测试中竟然测不出来&#xff0c;而且上线了好久。为啥会出现这种低级错误呢&#xff1f;第一是写的时候不够仔细认…

Day26:安全开发-PHP应用模版引用Smarty渲染MVC模型数据联动RCE安全

目录 新闻列表 自写模版引用 Smarty模版引用 代码RCE安全测试 思维导图 PHP知识点&#xff1a; 功能&#xff1a;新闻列表&#xff0c;会员中心&#xff0c;资源下载&#xff0c;留言版&#xff0c;后台模块&#xff0c;模版引用&#xff0c;框架开发等 技术&#xff1a;输…

2024 年中国高校大数据挑战赛赛题 C:用户对博物馆评论的情感分析完整思路以及源代码分享

博物馆是公共文化服务体系的重要组成部分。国家文物局发布&#xff0c; 2021 年我国新增备案博物馆 395 家&#xff0c;备案博物馆总数达 6183 家&#xff0c;排 名全球前列&#xff1b;5605 家博物馆实现免费开放&#xff0c;占比达 90%以上&#xff1b;全国 博物馆举办展览 3…

【深度学习笔记】6_5 RNN的pytorch实现

注&#xff1a;本文为《动手学深度学习》开源内容&#xff0c;部分标注了个人理解&#xff0c;仅为个人学习记录&#xff0c;无抄袭搬运意图 6.5 循环神经网络的简洁实现 本节将使用PyTorch来更简洁地实现基于循环神经网络的语言模型。首先&#xff0c;我们读取周杰伦专辑歌词…

Python操作Redis 各种数据类型

本文将深入探讨如何使用Python操作Redis&#xff0c;覆盖从基础数据类型到高级功能的广泛主题。无论是字符串、列表、散列、集合还是有序集合&#xff0c;我们将一一解析&#xff0c;同时提供丰富的代码示例帮助读者更好地理解和应用。除此之外&#xff0c;本文还将介绍Redis的…

【20240309】WORD宏设置批量修改全部表格格式

WORD宏设置批量修改全部表格格式 引言1. 设置表格文字样式2. 设置表格边框样式3. 设置所有表格边框样式为075pt4. 删除行参考 引言 这两周已经彻底变为office工程师了&#xff0c;更准确一点应该是Word工程师&#xff0c;一篇文档动不动就成百上千页&#xff0c;表格图片也是上…

STM32之串口中断接收UART_Start_Receive_IT

网上搜索了好多&#xff0c;都是说主函数增加UART_Receive_IT()函数来着&#xff0c;实际正确的是UART_Start_Receive_IT()函数。 —————————————————— 参考时间&#xff1a;2024年3月9日 Cube版本&#xff1a;STM32CubeMX 6.8.1版本 参考芯片&#xff1a…

Svg Flow Editor 原生svg流程图编辑器(二)

系列文章 Svg Flow Editor 原生svg流程图编辑器&#xff08;一&#xff09; 说明 这项目也是我第一次写TS代码哈&#xff0c;现在还被绕在类型中头昏脑胀&#xff0c;更新可能会慢点&#xff0c;大家见谅~ 目前实现的功能&#xff1a;1. 元件的创建、移动、形变&#xff1b;2…

【C语言】字符指针

在指针的类型中我们知道有一种指针类型为字符指针char* 一般使用&#xff1a; int main() { char ch w; char *pc &ch; *pc w; return 0; } 还有一种使用方式&#xff0c;如下&#xff1a; int main() { const char* pstr "hello bit.";//这⾥是把⼀个字…

plantUML使用指南之序列图

文章目录 前言一、序列图1.1 语法规则1.1.1 参与者1.1.2 生命线1.1.3 消息1.1.4 自动编号1.1.5 注释1.1.6 其它1.1.7 例子 1.2 如何画好 参考 前言 在软件开发、系统设计和架构文档编写过程中&#xff0c;图形化建模工具扮演着重要的角色。而 PlantUML 作为一种强大且简洁的开…

【stm32 外部中断】

中断&#xff1a;在主程序运行过程中&#xff0c;出现了特定的中断触发条件&#xff08;中断源&#xff09;&#xff0c;使得CPU暂停当前正在运行的程序&#xff0c;转而去处理中断程序&#xff0c;处理完成后又返回原来被暂停的位置继续运行 中断优先级&#xff1a;当有多个中…

LoadBalancer (本地负载均衡)

1.loadbalancer本地负载均衡客户端 VS Nginx服务端负载均衡区别 Nginx是服务器负载均衡&#xff0c;客户端所有请求都会交给nginx&#xff0c;然后由nginx实现转发请求&#xff0c;即负载均衡是由服务端实现的。 loadbalancer本地负载均衡&#xff0c;在调用微服务接口时候&a…

考研复习C语言初阶(4)+标记和BFS展开的扫雷游戏

目录 1. 一维数组的创建和初始化。 1.1 数组的创建 1.2 数组的初始化 1.3 一维数组的使用 1.4 一维数组在内存中的存储 2. 二维数组的创建和初始化 2.1 二维数组的创建 2.2 二维数组的初始化 2.3 二维数组的使用 2.4 二维数组在内存中的存储 3. 数组越界 4. 冒泡…

【Java JVM】Class 文件的加载

Java 虚拟机把描述类的数据从 Class 文件加载到内存, 并对数据进行校验, 转换解析和初始化, 最终形成可以被虚拟机直接使用的 Java 类型, 这个过程被称作虚拟机的类加载机制。 与那些在编译时需要进行连接的语言不同, 在 Java 语言里面, 类的加载, 连接和初始化过程都是在程序…

解决阿里云服务器开启frp服务端,内网服务器开启frp客户端却连接不上的问题

解决方法&#xff1a; 把阿里云自带的Alibabxxxxxxxlinux系统 换成centos 7系统&#xff01;&#xff01;&#xff01;&#xff01; 说一下我的过程和问题&#xff1a;由于我们内网的服务器在校外是不能连接的&#xff0c;因此我弄了个阿里云服务器做内网穿透&#xff0c;所谓…

大模型学习过程记录

一、基础知识 自然语言处理&#xff1a;能够让计算理解人类的语言。 检测计算机是否智能化的方法&#xff1a;图灵测试 自然语言处理相关基础点&#xff1a; 基础点1——词表示问题&#xff1a; 1、词表示&#xff1a;把自然语言中最基本的语言单位——词&#xff0c;将它转…

你应该打好你的日志,起码避免被甩锅

大家好&#xff0c;我是蓝胖子,相信大家或多或少都有这样的经历&#xff0c;当你负责的功能出现线上问题时&#xff0c;领导第一时间便是找到你询问原因&#xff0c;然而有时问题的根因或许不在你这儿&#xff0c;只是这个功能或许依赖了第三方或者内部其他部门&#xff0c;这个…