美文网首页
day44-模型设计

day44-模型设计

作者: barriers | 来源:发表于2019-01-04 20:10 被阅读0次

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

    相关文章

      网友评论

          本文标题:day44-模型设计

          本文链接:https://www.haomeiwen.com/subject/dvyhrqtx.html