1模型设计部分参数
1.1迁移表中db_table
指定db_table参数,表示模型迁移时,映射到数据库中的表名称
如果没指定db_table参数,则数据库中模型映射的表名为:应用名(app)_模型名
1.2模型中的外键约束中的on_delete参数
on_delete=models.CASCADE:不能删除主表,从表相应数据可以被删除(默认)
on_delete=models.PROTECT:不让删主表,但可以删从表
on_delete=models.SET_NULL:删除主表,从表的关联字段(外键)设置为空
1.3模型中外键约束中的related_name参数
related_name:关联对象反向引用描述符
related_name='info':给反向引用描述符命名为info;如果不设置,则默认为模型名的全小写
2模型设计部分字段类型
CharField:字符串类型
TextField:存储长文本内容,前端的areatext标签
IntegerField:整型
ImageField:字符串类型,用于存图片
BooleanField:布尔,True或者False
DateTimeField:日期,年月日时分秒
DateField:年月日
FloatField:浮点类型
DecimalField:浮点类型,限制最大长度和小数点后的长度
unique:是否唯一
default:默认值
null:是否可以为空
primary_key:主键(电脑可以自己赋值)
auto_now_add:创建时,默认赋值为当前时间
auto_now:在创建或者修改时,默认赋值为当前时间(更新时只能用save方法更新)
max_length:最大长度
3一对一模型中给从表添加对象
一对一(OneToOneField),常写作(1:1),定义在模型中的任何一方都可以
存储:
关联字段存储1:stu_info.关联字段=关联对象
stu_info.stu=Student.objects.get(id=1)
关联字段存储2: stu_info.关联字段_id=主键id值
stu_info.stu_id=1
查询:
学生对象查拓展表对象:学生对象.拓展模型名称的小写
拓展表查询学生对象:拓展表对象.外键约束字段
学生与其紧急联系人之间为一对一模型关系
先在models中创建StudentInfo模型
class StudentInfo(models.Model):
s_no = models.CharField(max_length=10,null=False)
phone = models.CharField(max_length=11,null=True)
name = models.CharField(max_length=10,null=True)
设置stu字段并为其设置为1对1属性
stu = models.OneToOneField(Student,on_delete=models.SET_NULL,
related_name='info',null=True)
在对从表添加数据并为其主键赋值时,有两种写法
stu_info(从表对象).stu(从表字段)=Student.objects.get(id=1)(主表具体的对象)
stu_info.stu_id(外键)=1(主表对应的主键);功能都是相同的。
3.1对外键赋值方法一
def add_stu_info(request):
stu_info = StudentInfo()
stu_info.s_no='12556'
stu_info.phone='13981366521'
stu_info.name='小王'
stu_info.stu=Student.objects.get(id=1)
stu_info.save()
return HttpResponse('创建拓展信息成功')
3.2对外键赋值方法二
def add_stu_info(request):
stu_info = StudentInfo()
stu_info.s_no='12556'
stu_info.phone='13981366521'
stu_info.name='小王'
stu_info.stu_id=1
stu_info.save()
return HttpResponse('创建拓展信息成功')
4一对一模型中通过主表查询从表(不用related_name参数)
过程:
1.查询主表(学生)对象
2.通过主表(学生)对象查询从表(拓展表)对象
在主表查从表获取连表条件时有两种写法:
stu_info=StudentInfo.objects.filter(stu(从表字段)=stu(主表对象)).first()
stu_info=StudentInfo.objects.filter(stu_id(从表字段)=stu.id(主表对象的属性)).first()
4.1查询方法1
def sel_phone_by_stu(request):
stu=Student.objects.filter(s_name='小明').first()
stu_info=StudentInfo.objects.filter(stu=stu).first()
phone=stu_info.phone
return HttpResponse('查询电话成功')
4.2查询方法2
def sel_phone_by_stu(request):
stu=Student.objects.filter(s_name='小明').first()
stu_info=StudentInfo.objects.filter(stu_id=stu.id).first()
phone=stu_info.phone
return HttpResponse('查询电话成功')
5一对一模型中通过主表查询从表(用related_name参数)
反向引用过程:
1.查询学生对象
2.反向查询;关联模型对象,关联另外一个模型的名称的小写
5.1使用模型中默认的related_name参数
模型中默认的related_name参数为模型名的全小写
def sel_phone_by_stu2(request):
stu=Student.objects.filter(s_name='小明').first()
stu_info = stu.studentinfo #studentinfo反向引用符
phone=stu_info.phone
print(phone)
return HttpResponse('查询电话成功')
5.2使用设置的related_name参数
在模型中的主键中设置:stu = models.OneToOneField(Student,on_delete=models.SET_NULL,
related_name='info',null=True);将related_name设置为info
def sel_phone_by_stu2(request):
stu=Student.objects.filter(s_name='小明').first()
stu_info = stu.info #info反向引用符
phone=stu_info.phone
print(phone)
return HttpResponse('查询电话成功')
6一对一模型中通过从表查询主表
1.查询拓展表信息
2.查询学生对象
def sel_stu_by_info(request):
stu_info=StudentInfo.objects.filter(s_no='12556').first()
stu(学生对象)=stu_info(拓展对象).stu(拓展表字段)
print(stu.s_name)
return HttpResponse('查询成功')
7一对一模型中删除信息
当模型中为关联字段设置on_delete时,各参数的意义;
stu = models.OneToOneField(Student,on_delete=models.SET_NULL)
on_delete=models.CASCADE:不能删除主表,从表相应数据可以被删除(默认)
on_delete=models.PROTECT:不让删主表,但可以删从表
on_delete=models.SET_NULL:删除主表,从表的关联字段(外键)设置为空
def on_delete_stu(request):
Student.objects.filter(s_name='小明').delete()
return HttpResponse('删除成功')
8一对多模型中创建班级
一对多(ForeignKey),常写作(1:N),定义在多的一方
存储(给学生设置班级):
关联字段的存储1:学生对象.关系字段=关联模型对象
关联字段的存储2:学生对象.关系字段_id=关联表的主键id值
查询:
若没有定义related_name参数:
学生查询班级:班级对象=多的一方(学生)对象.关联字段
班级查询学生:一的一方(班级).关联模型名的小写_s
若定义了related_name参数:
学生查班级:多的一方(学生)对象.关联字段
班级查询学生:一的一方(班级).related_name参数名
先创建一个班级模型;班级与学生之间为一对多模型
class Grade(models.Model):
g_name=models.CharField(max_length=10,unique=True)
class Meta:
db_table='grade'
def add_grade(request):
Grade.objects.create(g_name='java1807')
return HttpResponse('添加班级成功')
9给学生设置班级
def stu_grade(request):
stu=Student.objects.get(pk=4)
stu.g_id=1 #给该对象的g_id属性(班级)赋值为1
stu.save()
return HttpResponse('分配学生班级成功')
10通过学生查询班级
def sel_grade_by_stu(request):
# 获取姓名叫小明2的学生对象
stu=Student.objects.get(s_name='小明2')
# 获取班级对象
grade=stu.g
print(grade.g_name)
return HttpResponse('查询成功')
11通过班级查询学生
def sel_stu_by_grade(request):
grade=Grade.objects.get(g_name='python1808')
stus=grade.student_set.all()
print(stus)#返回含有对象的列表
stus=grade.student_set
print(stus)#返回app.Student.None
return HttpResponse('查询成功')
12多对多模型中创建课程
多对多(ManyToManyField),常写作(N:M),可以定义在模型中的任何一方
多对多的存储同一对多一样;
1.在查询方面如果没有设置related_name参数;
当用课程查询学生时,查询方式为:课程对象.关联字段.filter()
用学生查询课程时,查询方式为:学生对象.关联模型名的小写_set
2.如果设置了related_name参数:
用课程查询学生:课程对象.关联字段.filter().all()
用学生查询课程:学生对象.related_name参数.filter().all()
创建一个课程表,课程与学生之间为多对多关系
class Course(models.Model):
c_name=models.CharField(max_length=10,unique=True)
# ManyToManyField字段定义在任何一个模型都可以
stu=models.ManyToManyField(Student,null=True)
class Meta:
db_table='course'
往课程表中添加课程
def add_course(request):
c_names=['大学英语','高等数学','岩浆岩岩石学',
'线性代数','概率论','运筹学']
for name in c_names:
cou = Course()
cou.c_name=name
cou.save()
return HttpResponse('添加课程成功')
13通过中间表添加删除学生或者课程
13.1给学生添加课程
def add_s_c(request):
cou=Course.objects.get(c_name='高等数学')
stu=Student.objects.get(s_name='妲己')
stu.course_set.add(cou)
return HttpResponse('添加中间表成功')
13.2给课程添加学生
def add_s_c(request):
cou=Course.objects.get(c_name='高等数学')
stu=Student.objects.get(s_name='妲己')
cou.stu(学生模型中反向引用符).add(stu(学生对象))
return HttpResponse('添加中间表成功')
13.3学生删除课程
def add_s_c(request):
cou=Course.objects.get(c_name='高等数学')
stu=Student.objects.get(s_name='妲己')
stu.course_set.remove(cou)
return HttpResponse('添加中间表成功')
14前端设计
14.1配置
在settings.py文件中定义TEMPALTES的目录地址第58行添加如下文字:'DIRS': [os.path.join(BASE_DIR,'templates')],
os.path.join(BASE_DIR,'templates')中BASE_DIR表示第16行的BASE_DIR获取到的文件位置,templates表示含有网页文件的文件夹;os.path.join('a','b')表示文件路径:a//b
14.2后端渲染模板
使用render()渲染模板
传递参数给模板,render(request,模板名,{key1:value1,key2:value2})
from django.shortcuts import render
def index(request):
stus=Student.objects.all()
return render(request,'index.html',{'a':stus})
14.3前端渲染模板
1.解析变量:{{变量}}
2.解析标签:{% 标签 %}{% endfor标签 %}
{{ a }} #解析变量
#换行标签
{% for stu in a %} #for标签
姓名:{{ stu.s_name }}
年龄:{{ stu.s_age }}
班级:{{ stu.g.g_name }}
选课:
{% for c in stu.course_set.all %}
{{ c.c_name }}
{% endfor %}
{% endfor %} #结束标签
15总结
15.1聚合函数及模糊查询
聚合函数(Avg,Max,Sum,Count)的使用
模型名.objects.筛选条件.aggregate(聚合函数('聚合条件'))
模糊查询(contains、startswith及endswith)
模型名.objects.filter(查询字段__startswith='查询内容')
15.2related_name参数
模型中外键约束中的related_name参数:
related_name:关联对象反向引用描述符;当为一对一关系时,related_name参数默认为对应模型的模型名全小写;当为一对多或者多对多关系时,默认为对应模型的模型名小写_set
15.3用主表给从表关联字段赋值
当用主表中的信息(主键)给从表的关联字段(外键)赋值时:
从表对象.关联字段=主表对象(主表对象要唯一) 或者 从表对象.关联字段_id=要赋的主表对象对应的主键具体值
15.4不用related_name用主表查从表
当不用related_name参数查询时:
当用主表查从表时(无关联参数的一方查有关联参数的一方),先生成主表对象;然后从表对象=从表模型名.objects.filter(关联字段=主表对象/关联字段_id=主表对象.id).first()
15.5用related_name查询
当用related_name参数查询时:
当用主表查从表时(无关联参数的一方查有关联参数的一方),需要用related_name参数生成从表对象(从表对象=主表对象.related_name参数/当为一对多关系时,还要在后面接上.all()才是查询集集合)
当用从表查主表时(有关联参数的一方查无关联参数的一方),直接用关联字段生成主表对象(主表对象=从表对象.关联字段)
15.6多对多中间表数据的添加与删除
当为多(M)对多(N)关系时:
往中间表中添加数据:M对象.N的related_name参数.add(N对象)
在中间表中删除数据:M对象.N的related_name参数.remove(N对象)