当我们讨论CRUD的时候,实际在讨论什么
目录
为什么要看crud的映射
实际的业务中,我们一定要和数据库打交道,以mysql为例,我们可以通过他记录结构化的数据,事实上我们应该把我们需要的业务主体抽象为一个个表,数据库是记录数据的重要工具
作为一个crud的程序员,第一时间能想到的就是:
SELECT * FROM users
INSERT INTO users (name, age) VALUES ('张三', 23)
UPDATE users SET name = '李四' where id = 1
DELETE FROM users where id = 1
但我在项目中并不会编写具体的sql,更多的是使用框架封装好的orm
django中编写crud的接口
假设一个简单的场景:
- 学生信息:姓名,性别,年龄
- 学生信息的增删查改接口
python
"""
models.Stu
"""
from django.db import models
class Stu(models.Model):
class Gender(models.TextChoices):
MALE = 'M', '男'
FEMALE = 'F', '女'
name = models.CharField(max_length=50)
age = models.IntegerField()
gender = models.CharField(
max_length=1,
choices=Gender.choices,
default=Gender.MALE,
)
def __str__(self):
return self.name
上面是一个学生的类,里面包含三个字段,姓名,年龄,性别,因为没有显式的添加主键,django的orm会给我们添加一个id(AutoField)
python
"""
Stu对应的视图函数
"""
from django.http import HttpResponse, JsonResponse
from django.shortcuts import get_object_or_404
from .models import Stu
# 查:列表
def Stu_list(request):
"""
path('Stu/', orm_research_views.Stu_list),
/Stu/
"""
Stus = Stu.objects.all()
data = [
{
'id': u.id,
'name': u.name,
'age': u.age,
'gender': u.gender,
'gender_display': u.get_gender_display(),
}
for u in Stus
]
return JsonResponse({'data': data})
# 查:单条
def Stu_detail(request, Stu_id):
"""
path('Stu/<int:Stu_id>/', orm_research_views.Stu_detail),
/Stu/<int:stu_id>/
"""
Stu = get_object_or_404(Stu, id=Stu_id)
return JsonResponse({
'id': Stu.id,
'name': Stu.name,
'age': Stu.age,
'gender': Stu.gender,
'gender_display': Stu.get_gender_display(),
})
# 增
def Stu_create(request):
"""
path('Stu/create/', orm_research_views.Stu_create),
/Stu/create/
"""
if request.method != 'POST':
return JsonResponse({'error': 'method not allowed'}, status=405)
name = request.POST.get('name')
age = request.POST.get('age')
gender = request.POST.get('gender', Stu.Gender.MALE)
if not name or not age:
return JsonResponse({'error': 'name and age are required'}, status=400)
Stu = Stu.objects.create(
name=name,
age=int(age),
gender=gender,
)
return JsonResponse({'id': Stu.id, 'msg': 'created'})
# 改
def Stu_update(request, Stu_id):
"""
path('Stu/<int:Stu_id>/update/', orm_research_views.Stu_update),
/Stu/<int:stu_id>/update/
"""
if request.method != 'POST':
return JsonResponse({'error': 'method not allowed'}, status=405)
Stu = get_object_or_404(Stu, id=Stu_id)
name = request.POST.get('name')
age = request.POST.get('age')
gender = request.POST.get('gender')
if name is not None:
Stu.name = name
if age is not None:
Stu.age = int(age)
if gender is not None:
Stu.gender = gender
Stu.save()
return JsonResponse({'id': Stu.id, 'msg': 'updated'})
# 删
def Stu_delete(request, Stu_id):
"""
path('Stu/<int:Stu_id>/delete/', orm_research_views.Stu_delete),
/Stu/<int:stu_id>/delete/
"""
if request.method != 'POST':
return JsonResponse({'error': 'method not allowed'}, status=405)
Stu = get_object_or_404(Stu, id=Stu_id)
Stu.delete()
return JsonResponse({'msg': 'deleted'})
以上是django中编写一个Stu类的crud的视图函数
里面没有显式的编写任何SQL,但是依旧可以对数据库进行操作,我们来分析一下是怎么做到的
ORM映射为真实SQL语句
关于前面这段视图函数,我认为重点关注的是:
- Stu类的实现
- models.Model
Stu类
从代码上看,我们把Stu的信息定义在这个类上面 但是这里的name、age、gender和普通的类属性不太一样
例如:name = "tom" 这只是一个普通的字符串属性
但是:name = models.CharField(max_length=50)创建的是一个Django的Field对象,这可以让Django了解到这个Stu的Model有哪些字段,以及对应的数据库信息。
因此我们先把这个类理解为:
使用一个Python类来描述数据库结构
models.Model
models.Model 是 Django 中所有数据库模型的基类。它的核心作用是:把 Python 类映射成数据库表,把类属性映射成表字段,让你用 Python 代码操作数据库,而不用直接写 SQL。
具体来说,它提供了以下几件事:
- 定义数据库结构
- 提供ORM操作接口
- 管理与数据库的同步(迁移数据库)
- 与Django其他组件集成
这些内容目前我还没有完全研究明白,后续研究好了再发布新的文章讨论
关于Django的ORM,这里只是浅显的讨论一下,还有objects对象,DRF序列化等没有讲到,如果有大佬有详细的解析,可以给我分享一下!!
下一篇见!!