前言
通過(guò)講mysql的系統(tǒng)组力,翻譯一遍,在django中通過(guò)創(chuàng)建model去和數(shù)據(jù)庫(kù)中的表進(jìn)行一一映射,并且通過(guò)ORM封裝 的處理方式去練習(xí)這一道習(xí)題琳状,并寫(xiě)出如下的解題答案
1.數(shù)據(jù)庫(kù)準(zhǔn)備
在model中定義數(shù)據(jù)庫(kù),其中的性別,男的存1盒齿,女的存0念逞。
class Student(models.Model):
stuname = models.CharField(max_length=20)
stusex = models.BooleanField()
stubirth = models.DateField()
stutel = models.CharField(max_length=255)
class Meta:
db_table = 'student'
2.數(shù)據(jù)庫(kù)遷移
python manage.py makemigrations
python manage.py migrate
3. 數(shù)據(jù)插入
3.1 使用表單form提交post請(qǐng)求數(shù)據(jù)
<form action="/app/addStu/" method="post">
stuname: <input type="text" name="name">
stusex: <input type="text" name="sex">
stubirth: <input type="date" name="birth">
stutel: <input type="text" name="tel">
<input type="submit" value="提交">
</form>
3.2 獲取post請(qǐng)求困食,獲取請(qǐng)求數(shù)據(jù),并且創(chuàng)建數(shù)據(jù)
方法1:獲取類(lèi)對(duì)象進(jìn)行save()保存
stu = Student()
stu.stuname = stuname
stu.stusex = sex
stu.stubirth = birth
stu.stutel = tel
stu.save()
方法2:使用create()方法
Student.objects.create(stuname=stuname,
stusex=sex,
stubirth=birth,
stutel=tel)
方法3:使用初始化
在Student模型中重構(gòu)__init__()方法翎承,添加如下代碼
def __init__(self, name, birth=None, sex=None硕盹,tel=None):
super().__init__()
self.stuname = name
self.stubirth = birth
self.stusex = sex
self.stutel = tel
# 視圖函數(shù)中定義創(chuàng)建學(xué)習(xí)信息的方法為:
stu = Student('小草', 18, 1, 12331244323)
stu.save()
注意:重構(gòu)init方法的時(shí)候,一定要使用super().init()叨咖,否則會(huì)報(bào)studen對(duì)象沒(méi)有_state的屬性瘩例。
4. 查詢(xún)所有的學(xué)生信息
使用all()方法獲取所有的數(shù)據(jù)
Student.objects.all()
4. 查詢(xún)所有女學(xué)生的姓名和出生日期
Student.objects.filter(stusex=0)
或者
Student.objects.exclude(stusex=1)
其中:
filter():返回符合條件的數(shù)據(jù)
exclude():過(guò)濾掉符合條件的數(shù)據(jù)
5.查詢(xún)所有的學(xué)生,按照id從大到小排序
Student.objects.all().order_by('-id')
其中:
order_by('id'):表示按照id升序的排列
order_by('-id'):表示按照id降序的排列
6. 查詢(xún)所有的學(xué)生信息甸各,并序列化
Student.objects.all().values()
Student.objects.all().values('s_name', 's_age')
7.查詢(xún)所有80后學(xué)生的姓名垛贤、性別和出生日期(篩選)
Student.objects.filter(stubirth__gte='1980-01-01',
stubirth__lte='1990-01-01')
8.查詢(xún)名字中有王字的學(xué)生的姓名(模糊),like '%小%'趣倾, like '小%'聘惦,like '%小'
Student.objects.filter(s_name__contains='小')
Student.objects.filter(s_name__startswith='小')
Student.objects.filter(s_name__endswith='小')
9.查詢(xún)id等于1,2的學(xué)生信息
# select * from student where id in (1,2)
stus = Student.objects.filter(id__in=[1,2])
10. 獲取id為1的信息,get()和filter()的使用
Student.objects.filter(id=1)
Student.objects.get(id=1)
Student.objects.get(pk=1)
# get獲取不到數(shù)據(jù)會(huì)直接報(bào)錯(cuò), filter獲取不到數(shù)據(jù)是返回空
stus = Student.objects.get(pk=5)
Student.objects.filter(id=5)
# get只能返回一個(gè)數(shù)據(jù)儒恋,返回多個(gè)會(huì)報(bào)錯(cuò)
Student.objects.get(s_age=15) # 前提條件:數(shù)據(jù)庫(kù)中s_age為15的數(shù)據(jù)有多條
11.獲取所有學(xué)生(按照id降序)中第一個(gè)/最后一個(gè)學(xué)生信息
# 獲取按照id降序的第一個(gè)學(xué)生信息
Student.objects.all().order_by('-id')[0]
Student.objects.all().order_by('-id').first()
# 獲取所有學(xué)生(按照id降序)中最后一個(gè)學(xué)生信息
Student.objects.all().order_by('-id').last()
===========模型加參===========
1.建表
class Grade(models.Model):
g_name = models.CharField(max_length=10, unique=True, null=False)
class Meta:
db_table = 'grade'
class StudentInfo(models.Model):
address = models.CharField(max_length=50, null=True)
phone = models.CharField(max_length=11, null=True)
class Meta:
db_table = 'stu_info'
class Student(models.Model):
# 長(zhǎng)度為10善绎,且唯一不能為空的姓名s_name字段 CharField - 字符串類(lèi)型
s_name = models.CharField(max_length=10, unique=True, null=False)
# IntegerField - 整型字段
age = models.IntegerField(default=18)
# auto_now_add:表示第一次創(chuàng)建數(shù)據(jù)時(shí),自動(dòng)默認(rèn)為創(chuàng)建的時(shí)間
create_time = models.DateTimeField(auto_now_add=True)
# auto_now: 表示修改時(shí),自動(dòng)更新為修改時(shí)間
operate_time = models.DateTimeField(auto_now=True)
# 是否刪除
is_delete = models.BooleanField(default=0)
# 定義浮點(diǎn)數(shù)總長(zhǎng)度3位,小數(shù)點(diǎn)后1位(decimal_places=1)
yuwen = models.DecimalField(max_digits=3, decimal_places=1, null=True)
math = models.DecimalField(max_digits=3, decimal_places=1, null=True)
# 一對(duì)一:定義在關(guān)聯(lián)的兩個(gè)模型中的任何一方都可以
stuinfo = models.OneToOneField(StudentInfo, related_name='stu', on_delete=models.CASCADE, null=True)
# 一對(duì)多:只能定義在‘多’的一方
grade = models.ForeignKey(Grade, related_name='stu', on_delete=models.CASCADE, null=True)
class Meta:
db_table = 'student'
2.數(shù)據(jù)庫(kù)遷移
python manage.py makemigrations
python manage.py migrate
模型對(duì)應(yīng)關(guān)系描述如下:
1:1 一對(duì)一 OneToOneField
1:N 一對(duì)多 ForeignKey
M:N 多對(duì)多 ManyToManyField 會(huì)自動(dòng)建一個(gè)中間表
在views.py文件中
def add_stu_info(request):
if request.method == 'GET':
# 向拓展表中添加信息
stu_info = StudentInfo()
stu_info.phone = '13545455433'
stu_info.save()
s_id = stu_info.id
stu = Student.objects.filter(s_name='小明').first()
# 第一種寫(xiě)法: 學(xué)生對(duì)象.OneToOneField字段 = 關(guān)聯(lián)對(duì)象
stu.stuinfo = stu_info
# 第二種寫(xiě)法: 學(xué)生對(duì)象.OneToOneField字段 = 關(guān)聯(lián)對(duì)象.id
stu.stuinfo_id = stu_info.id
stu.save()
return HttpResponse('添加拓展表信息')
def sel_stuinfo_by_stu(request):
if request.method == 'GET':
# 通過(guò)學(xué)生信息找拓展表信息
stu = Student.objects.get(s_name='小明')
# StudentInfo.objects.get(pk=stu.stuinfo_id) 等價(jià)于stu.stuinfo
# 學(xué)生對(duì)象(stu).OneToOneField字段(stuinfo)
stu.stuinfo
return HttpResponse('獲取拓展表信息成功')
def sel_stu_by_info(request):
if request.method == 'GET':
# 通過(guò)拓展表中的手機(jī)號(hào)碼找學(xué)生信息
stuinfo = StudentInfo.objects.filter(phone='13545455433').first()
# stu = Student.objects.filter(stuinfo=stuinfo)
# stu = Student.objects.filter(stuinfo_id=stuinfo.id) # 和上面一樣
# print(stu)
# 拓展表對(duì)象.關(guān)聯(lián)的模型名稱(chēng)小寫(xiě)
# stu = stuinfo.student # 和上面兩步一樣碧浊,這步很簡(jiǎn)單
# 定義related_name參數(shù), 拓展表對(duì)象.related_name值
stu = stuinfo.stu # 這的stu是onetonoe字段的related_name參數(shù),它和上面那步是互斥的
print(stu)
return HttpResponse('通過(guò)拓展表信息查詢(xún)學(xué)生表信息')
def add_grade(request):
if request.method == 'GET':
# 添加班級(jí)信息, 并給學(xué)生分配班級(jí)
names = ['Python班級(jí)', 'Java班級(jí)', 'Php班級(jí)', 'C++班級(jí)']
for name in names:
if Grade.objects.filter(g_name=name).exists():
Grade.objects.creat(g_name=name)
# 分配班級(jí)
stus = Student.objects.filter(pk_in=[5, 6, 7, 10, 11, 12]).all()
g = Grade.objects.filter(g_name='Python班級(jí)').first()
for stu in stus:
stu.grade = g
# stu.grade_id = g.id
stu.save()
return HttpResponse('添加班級(jí)和學(xué)生信息')
def sel_grade_by_stu(request):
if request.method == 'GET':
# 通過(guò)學(xué)生查詢(xún)班級(jí)信息
stu = Student.objects.filter(s_name='小明').first()
g = stu.grade
print(g)
# 班級(jí)查詢(xún)學(xué)生
stus = g.student_set.all() # 和下面一樣
stus = g.stu.all() # 定義了related_name='stu'涂邀,
但是用了related_name之后,就不能用_set了
return HttpResponse('通過(guò)學(xué)生查詢(xún)班級(jí)成功')
多對(duì)多
先聲明兩個(gè)類(lèi)Course, Student
class Course(models.Model):
c_name = models.CharField(max_length=10, unique=True, null=False)
class Meta:
# 指定表名
db_table = 'course'
class Student(models.Model):
# 長(zhǎng)度為10,且唯一不能為空的姓名s_name字段 CharField - 字符串類(lèi)型
s_name = models.CharField(max_length=10, unique=True, null=False)
# IntegerField - 整型字段
age = models.IntegerField(default=18)
# auto_now_add:表示第一次創(chuàng)建數(shù)據(jù)時(shí)箱锐,自動(dòng)默認(rèn)為創(chuàng)建的時(shí)間
create_time = models.DateTimeField(auto_now_add=True)
# auto_now: 表示修改時(shí),自動(dòng)更新為修改時(shí)間
operate_time = models.DateTimeField(auto_now=True)
# 是否刪除
is_delete = models.BooleanField(default=0)
# 定義浮點(diǎn)數(shù)總長(zhǎng)度3位,小數(shù)點(diǎn)后1位(decimal_places=1)
yuwen = models.DecimalField(max_digits=3, decimal_places=1, null=True)
math = models.DecimalField(max_digits=3, decimal_places=1, null=True)
# 多對(duì)多
course = models.ManyToManyField(Course, related_name='stu')
class Meta:
db_table = 'student'
views.py文件中
def add_course(request):
if request.method == 'GET':
# 添加課程信息
names = ['大學(xué)語(yǔ)文', '日語(yǔ)', '數(shù)電', '模電']
for name in names:
cou = Course()
cou.c_name = name
cou.save()
return HttpResponse('添加課程成功')
def sel_cou_by_stu(request):
if request.method == 'GET':
# 查詢(xún)id為1的學(xué)生所選擇的課程信息
stu = Student.objects.get(pk=1)
# 學(xué)生查找課程
stu.course
# 課程查詢(xún)學(xué)生
cou = Course.objexts.get(pk=1)
cou.student_set.all() # student是小寫(xiě)的類(lèi)名, 沒(méi)有related_name之前可以用
cou.stu.all()
return HttpResponse('多對(duì)多的查詢(xún)成功')
def add_del_stu_cou(request):
if request.method == 'GET':
# 增刪中間表的信息
# 給小王分配'日語(yǔ)', '數(shù)電', '模電'
stu = Student.objects.filter(s_name='小明').first()
cou1 = Course.objects.get(c_name='日語(yǔ)')
cou2 = Course.objects.get(c_name='數(shù)電')
cou3 = Course.objects.get(c_name='模電')
# 新增中間表數(shù)據(jù)
stu.course.add(cou1)
stu.course.add(cou2)
stu.course.add(cou3) # add方法加入課程(flask中用的append), 此時(shí)中間表就有信息了
# cou1.stu.add(學(xué)生對(duì)象) # 和上面一樣的
# 刪除中間表數(shù)據(jù) stu.course此時(shí)有3門(mén)課程
stu.course.remove(cou2)
stu.course.remove(cou3) # 此時(shí)刪掉了數(shù)電和模電課程
return HttpResponse('操作中間表信息成功')
def on_delete_stu(request):
if request.method == 'GET':
# 演示刪除, on_delete參數(shù)的效果
stuinfo = StudentInfo.objects.get(id=6)
stuinfo.delete()
# models.CASCADE 表示:主鍵所在行的數(shù)據(jù)被刪, 外鍵所在行的數(shù)據(jù)也會(huì)被刪
# models.PROTECT 表示:主鍵有對(duì)應(yīng)的外鍵數(shù)據(jù)時(shí), 不讓刪除主鍵的數(shù)據(jù)
# models.SET_NULL 表示:主鍵刪除, 外鍵置空
# 常用的就上面三個(gè)
return HttpResponse('on_delete演示成功')
模型關(guān)聯(lián)關(guān)系
一對(duì)一
class A():
id = modules.IntegerFiled()
class B():
aa = mldels.OneToOneField(A,, on_delete=models.CASCADE, null=True,related_name='cc')
- OneToOneField(關(guān)聯(lián)模型)
- 模型定義
- 關(guān)聯(lián)名 = models.OneToOneField(關(guān)聯(lián)的表名, related_name = '關(guān)系名', on_delete=models.CASCADE, null=True)
- 已知 A 對(duì)象 a 查詢(xún) B 對(duì)象
- 當(dāng) related_name 沒(méi)定義時(shí): a.b
- 當(dāng) related_name = 'cc'時(shí): a.cc
- 已知 B 對(duì)象 b 查詢(xún) A 對(duì)象 b.aa
- 一對(duì)一:定義在關(guān)聯(lián)的兩個(gè)模型中的任意一方都可以
一對(duì)多
class A():
id
class B():
aa = models.ForeignKey(A, on_delete=models.CASCADE, null=True,related_name='cc')
- ForeignKey(關(guān)聯(lián)模型)
- 模型定義
- aa = ForeignKey(A)
- 已知 A 對(duì)象 a比勉,查詢(xún) B 對(duì)象
- 當(dāng) related_name 沒(méi)定義時(shí): a.b_set
- 當(dāng) related_name = 'cc'時(shí): a.cc
- 已知 B 對(duì)象 b 查詢(xún) A 對(duì)象 b.aa
- 一對(duì)多:定義在'多'的一方
多對(duì)多
- course = models.ManyToManyField(Course 要進(jìn)行關(guān)聯(lián)的表的名字,related_name='stu') 會(huì)自動(dòng)生成中間文件,中間文件的表名為 course
- 查詢(xún) id 為 1 的學(xué)生課程信息
- stu = Student.objects.get(pk=1)
- 學(xué)生查詢(xún)課程
- stu.course
- 課程查詢(xún)學(xué)生
- cou = Course.objects(pk=1)
- 當(dāng) related_name 沒(méi)定義時(shí): cou.student_set.all()
- 當(dāng) related_name 定義時(shí): cou.stu.all()
- 增加中間表信息
- stu = Student.objects.filter(s_name = '小明').first()
- cou1 = Course.objects.get(c_name='日語(yǔ)')
- stu.course.add(cou1)
- 刪除中間表信息
- stu.course.remove(cou1)
- on_delete 參數(shù)
- models.CASCADE 表示: 主鍵所在行的數(shù)據(jù)被刪驹止,外鍵所在行的數(shù)據(jù)也會(huì)被刪
- models.PROTECT 表示: 主鍵有對(duì)應(yīng)的外鍵數(shù)據(jù)時(shí)浩聋,不讓刪除主鍵的數(shù)據(jù)
- models.SET_NULL 表示: 主鍵刪除,外鍵置空
- 注意: ManyToManyFiled 定義的字段定義在任何一個(gè)關(guān)聯(lián)模型中都可以