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 }} #解析变量
<br> #换行标签
{% for stu in a %} #for标签
    <p>姓名:{{ stu.s_name }}
        年龄:{{ stu.s_age }}
        班级:{{ stu.g.g_name }}
        选课:
        {% for c in stu.course_set.all %}
            {{ c.c_name }}
            {% endfor %}
    </p>
{% 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对象)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容

  • 原文:https://my.oschina.net/liuyuantao/blog/751438 查询集API 参...
    阳光小镇少爷阅读 3,802评论 0 8
  • Django 1.8.2 文档Home | Table of contents | Index | Modules...
    轩辕小爱阅读 2,343评论 0 2
  • 今晚,看了一场世界杯比赛,巴西对哥斯达黎加。经过九十八分钟的鏖战,巴西凭借补时的两粒进球战胜了对手。比赛结束的那一...
    善为道者阅读 249评论 0 0
  • 让我们从已被临床验证的科技和复杂的护肤配方着手,看看如何解决色素沉着过度的问题。 1.防晒 对付黑斑最重要的方法很...
    社群经济财务自由阅读 573评论 0 0
  • 遥映人间冰雪样, 暗香幽浮曲临江遍识天下英雄路, 俯首江左有梅郎 序:一曲琅琊心憔悴,风中眼泪谁来陪?世间恩仇道不...
    怡nid阅读 653评论 0 11