day44-模型设计

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对象)

你可能感兴趣的:(day44-模型设计)