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,一经查实,立即删除!

相关文章

Linux unset命令教程:如何删除环境变量或函数(附实例详解和注意事项)

Linux unset命令介绍 unset命令用于删除环境变量或函数。如果你不再需要某个环境变量或函数&#xff0c;你可以使用unset命令将其删除。 Linux unset命令适用的Linux版本 unset命令在大多数Linux发行版中都是可用的&#xff0c;包括Debian、Ubuntu、Alpine、Arch Linux、Kal…

鸿蒙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;输…

Selenium库快速查找网页元素及执行浏览器模拟操作

Selenium 是一个自动化测试工具&#xff0c;主要用于模拟用户在网页上的行为&#xff0c;进行自动化测试。它支持多种浏览器&#xff0c;并且可以在多种操作系统上运行。以下是 Selenium 库的一些主要特点和用途&#xff1a; 网页自动化测试&#xff1a; Selenium 可以模拟用户…

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的…

JVM和JVM内存管理

Java虚拟机&#xff08;Java Virtual Machine 简称JVM&#xff09;是运行所有Java程序的抽象计算机&#xff0c;是Java语言的运行环境&#xff0c;它是Java 最具吸引力的特性之一。Java源代码经过编译器编译后生成与平台无关的字节码文件&#xff08;.class文件&#xff09;。当…

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

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

计算机视觉(CV)自然语言处理(NLP)大模型应用,如何实现小模型

在人工智能领域&#xff0c;大模型已经成为引领创新和进步的重要推动力。它们不仅在自然语言处理、计算机视觉等任务中展现了强大的性能&#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…

完全背包问题(一般写法与空间优化写法)

题目 有 N 种物品和一个容量是 V 的背包&#xff0c;每种物品都有无限件可用。 第 i 种物品的体积是 vi&#xff0c;价值是 wi。 求解将哪些物品装入背包&#xff0c;可使这些物品的总体积不超过背包容量&#xff0c;且总价值最大。 输出最大价值。 输入格式 第一行两个整…

最多几个直角三角形python

最多几个直角三角形 问题描述思路代码实现 问题描述 最多可以组成几个直角三角形&#xff0c;一个边只能用一次。 输入描述&#xff1a; 第一行输入一个正整数T&#xff08;1<&#xff1d;T<&#xff1d;100&#xff09;&#xff0c;表示有T组测试数据. 对于每组测试数据…

贪心算法: 奶牛做题

5289. 奶牛做题 - AcWing题库 贝茜正在参加一场奶牛智力竞赛。 赛事方给每位选手发放 n 张试卷。 每张试卷包含 k 道题目&#xff0c;编号 1∼k。 已知&#xff0c;不同卷子上的相同编号题目的难度相同&#xff0c;解题时间也相同。 其中&#xff0c;解决第 i 道题&#xff08;…

【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 作为一种强大且简洁的开…