A1025-北京-小花生
作者归档:Fidum
32 ORM之多对多添加记录
多对多关系,会有一张新的表进行存储,这里我们接上回,添加学生的时候,需要把学生选的课程一并添加到数据库中。
@students.post('/students')
async def add_students(student_in: StudentIn):
# 插入数据
# 方式二
student = await Student.create(name=student_in.name,pwd=student_in.pwd,student_number=student_in.student_number,classes_id=student_in.classes_id)
# 添加多对多记录
courses = await Courses.filter(id__in=student_in.courses)
print("courses", courses)
await student.courses.add(*courses)
print("student", student.courses)
return student
courses = await Courses.filter(id__in=student_in.courses)
这句就是在课程表中过滤学生选的课程idawait student.courses.add(*courses)
这句就是将学生选的课,一行一行插入到多对多关系表中
比如,我添加一个学生kuxie,除了基本信息外,他还选了id是6和7的课程(在courses表中可以查看)。
在文档中测试:
点击execute后,查看各表:
student表:
courses表:
多对多关系表:
学生和选的课程关系存储成功。
31 ORM 添加表记录
FastAPI tortoise ORM添加数据,在此接口方法下实现:
方式一:
@students.post('/students')
async def add_students(stu: Student):
return {"msg": "添加学生"}
传入json,并且做校验
class StudentIn(BaseModel):
# id : int # 可以不传
name: str
pwd: str
student_number: int
# 在数据库中,这个字段就变成了classes_id
classes_id: int
courses: List[int] = []
@field_validator('name')
@classmethod
def name_must_not_be_empty(cls, v):
if not v:
raise ValueError('Name cannot be empty')
return v
@students.post('/students')
async def add_students(student_in: StudentIn):
# 插入数据
# 方式一
# 先实例化
student = Student(name=student_in.name,pwd=student_in.pwd,student_number=student_in.student_number,classes_id=student_in.classes_id)
# 这里的classes_id就是一对多的传参了
# 然后存入数据库
await student.save()
return "添加了一个学生"
id我们之前设置过,是自增的:
mysql> desc student;
+----------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+-------------+------+-----+---------+----------------+
| id | int | NO | PRI | NULL | auto_increment |
| name | varchar(32) | NO | | NULL | |
| pwd | varchar(32) | NO | | NULL | |
| student_number | int | NO | | NULL | |
| classes_id | int | NO | MUL | NULL | |
+----------------+-------------+------+-----+---------+----------------+
5 rows in set (0.00 sec)
方式二:
@students.post('/students')
async def add_students(student_in: StudentIn):
# 方式二
student = await Student.create(name=student_in.name,pwd=student_in.pwd,student_number=student_in.student_number,classes_id=student_in.classes_id)
return student
以上代码的测试,都可以通过FastAPI自带的接口文档进行测试。
30 ORM响应页面数据
前后端分离的场景下,用户访问的是前端服务器,后端开发的接口是给前端用的,这个要谨记。
了解一下前后端不分离的模式
@student.get("/index.html")
async def getAllStudent():
students = await Student.all()
return students
这里直接返回的话,返回的是json的数据,可以在接口文档中看的很清楚。
前后端不分离的话,我们需要将数据嵌入前端中,然后返回给用户。
# 需要导入jinja2
from fastapi.templating import Jinja2Templates
from fastapi import Request
@students.get('/students')
async def get_all_students(request: Request): # 这里必须携带Request的实例
all_students = await Student.all()
templates = Jinja2Templates(directory=r".\chapter3\学习ORM\apis\templates")
return templates.TemplateResponse(
"index.html",{ # 模板文件写这里
"request": request,
"students": all_students #传递的参数写这里
}
)
模板文件需要在合适的位置编辑好,数据插入的位置,类似这样
<html>
<body>
<ul>
{% for student in students %}
<li>姓名:{{ student.name }}, 学号:{{ student.student_number }}</li>
{% endfor %}
</ul>
</body>
</html>
再尝试访问,就可以看到返回的渲染后的页面了
然后 老师讲了一下bootstrap的一些用法,看看就好。
29 选课系统之ORM查询操作
tortoise ORM具体操作
29 选课系统之ORM查询操作
学生选课为例
先手动在class表中添加几条记录,用insert也好、用pycharm的数据库插件也好、用navicat也好
id | 班级 |
---|---|
13 | 计算机1班 |
14 | 计算机2班 |
15 | 软件1班 |
teacher表也添加几条记录
id | name | pwd | tno |
---|---|---|---|
11 | xhs | 123 | 1 |
22 | dhs | 456 | 2 |
course表也添加几条记录
id | name | teacher_id |
---|---|---|
6 | python开发 | 11 |
7 | 操作系统原理 | 22 |
student也添加
id | name | pwd | sno | class |
---|---|---|---|---|
1 | tom | tom666 | 202501 | 13 |
2 | jerry | jerry666 | 202502 | 14 |
3 | tafei | tafei666 | 202503 | 14 |
student_course表添加
student_id | course_id |
---|---|
2 | 6 |
2 | 7 |
3 | 7 |
- 查询所有学生
在students_api.py文件中编辑,先导入我们定义的模型:
from mymodels import *
然后在查询所有学生的函数(可能是get_all_students)下面,进行tortoise ROM的查询操作:
students = Student.all()
# 查询所有记录,students是queryset的数据类型,可以遍历,
# 一张表相当于一个类,一条记录相当于一个对象的实例化
# 遍历的时候需要注意,不可以直接 for student in students: pass
# 这里需要变成异步任务,不然会报错
函数名前加上async,Student.all()前面加上await
async def get_all_students():
students = await Student.all()
... ...
过滤查询filter,返回的还是QuerySet,就算其中只有一个元素,也得按照元素位置取值或者遍历
# students = await Student.filter(name="tom")
students = await Student.filter(class_id=13)
过滤查询get,返回模型类对象,不用遍历
student = await Student.get(class_id=13)
# 可以直接使用对象的方法调用属性
print(student.name)
模糊查询
- 字段+两个下划线+查询符号
students = await Student.filter(sno__gt=202502) # sno__gt这里表示大于的意思 students = await Student.filter(sno__in=[202502,202503]) # 筛选其中的两个 students = await Student.filter(sno__range=[202501,202503]) # 范围查询
value查询
students = await Student.all().values("name")
students = await Student.filter(sno__gt=202502).values("name","sno")
# 这里就相当于只返回name字段的结果,相当于select name from xxx;
# 返回结果是字典组成的列表,返回多少条记录,该列表中就有多少个字典,
# 字典的格式和你查询的字段相对应,比如[{'name': 'xhs'}, {'name': 'dhs'}]或者
# [{'name': 'xhs', 'sno': 2}, {'name': 'dhs', 'sno': 3}]
今日书籍推荐(精神、激素相关)
- 《为什么斑马不得胃溃疡》(罗伯特·萨波尔斯基)
豆瓣8.8分,斯坦福神经生物学教授经典之作
重点:用动物比喻解释压力(皮质醇)如何摧毁身体,含肾上腺疲劳的现代人应对方案
适合人群:想理解压力与疾病关联的入门读者
- 《大脑里的快递员》(丹尼尔·亚蒙)
神经科学家写的神经递质科普
亮点:多巴胺/血清素章节用快递配送比喻解释机制,附自测量表
特别章节:第5章「肾上腺:你的压力开关」
- 《身体从未忘记》(贝塞尔·范德科尔克)
创伤与激素关系的普利策奖入围作品
实用价值:提供重置HPA轴(下丘脑-垂体-肾上腺轴)的具体方法
asyncio学习笔记
越来越多的框架往异步的方向发展,包括django后续的3.x版本也出了asgi版本,包括tornado,fastapi,aiohttp都在异步。
有趣的python【动态更新】
有趣的python,emm或者说叫蛋疼的python吧
web自动化-selenium
6月16日4:09记
这一次,我没有回家,却有望重获新生。
之前,北漂久了,人麻木了,回趟家是个很好的选择,回到家乡,看看儿时玩过的小溪、水库、充满回忆的学校,沐浴着家乡的阳光,呼吸着田埂间清新的气息,不用刻意做什么,能量瞬间充满全身,我感恩,我的童年是相对幸福的。起码,比现在幸福吧。
刚看完一集老高和小茉的视频,大概是讲如何消除烦恼,里面提到了一个小办法,就是有烦恼就写下来,我差点忘记了这个这个方法,本来之前用过的,人脑烦心事的处理总是混乱的,但写下来,你再用眼睛直观的去看,可能就清晰了。
我真的烦透了世俗中人的各种试探,甚至让我反胃,低略的手段让我感觉俗不可耐,有时间吧,试探我的人还是我平时认为关系还不错的,这样我就为难了,因为我不知道我是该精心编个故事骗骗你呢,还是风轻云淡的随意敷衍一下。什么?你想要我内心的正确答案?我靠,你真是不仅智商低下还爱做白日梦。
扯远了啊,说重获新生呢,谁家孩子有这样重获新生的。不行,有点困了~