day44-Django模型关系和模板

一、一对一模型

1.一对一模型关系:OneToOneField()
OneToOneField字段定义在关联的任何一个模型中都可以
OneToOneField等价于ForeignKey且约束unique=true

class A:
    name = CharField()

class B:
    a1 = OneToOneField(A)

正向查询:已知B的对象b,查询A对象:b.a1
反向查询:已知A的对象a,查询B对象:a.b
2.定义一对一模型关系

class Student(models.Model):
    name = models.CharField(max_length=10, unique=True)
    age = models.IntegerField(default=18)
    gender = models.BooleanField(default=1)
    # auto_now_add:创建数据时,默认create_time字段为当前时间
    create_time = models.DateTimeField(auto_now_add=True, null=True)
    # auto_now:修改时间,每次update学生信息时,修改该字段的时间为当前时间
    operate_time = models.DateTimeField(auto_now=True, null=True)
    chinese = models.DecimalField(max_digits=3, decimal_places=1, null=True)
    math = models.DecimalField(max_digits=3, decimal_places=1, null=True)

    g = models.ForeignKey(Grade, null=True)

    class Meta:
        # 指定Student模型映射到数据库中时,对应的表名
        db_table = 'student'


class StuInfo(models.Model):
    phone = models.CharField(max_length=11)
    address = models.CharField(max_length=100)

    stu = models.OneToOneField(Student)

    class Meta:
        db_table = 'stu_info'

3.正向查询

def sel_stu_by_phone(request):
    # 查询phone=13908771234的学生姓名
    stu_info = StuInfo.objects.get(phone='13908771234')
    stu = stu_info.stu
    name = stu.name
    
    return HttpResponse(name)

4.反向查询

def sel_info_by_stu(request):
    # 查询杰克的电话号码
    """
    方法一:
    stu = Student.objects.filter(name='杰克').first()
    stu_info = StuInfo.objects.filter(stu_id=stu.id).first()
    方法二:
    stu_info = StuInfo.objects.filter(stu=stu).first()
    """

    # 方法三:
    stu = Student.objects.filter(name='杰克').first()
    stu = stu.stuinfo
    phone = stu.phone

    return HttpResponse(phone)


二、一对多模型

1.一对多模型关系:ForeignKey()
Foreignkey字段必须定义在多的一方

class A:
    name = CharField()

class B:
    a1 = ForeignKey(A)

正向查询:已知B的对象b,查询A对象:b.a1
反向查询:已知A的对象a,查询B对象:a.b_set
2.定义一对多模型关系

class Student(models.Model):
    name = models.CharField(max_length=10, unique=True)
    age = models.IntegerField(default=18)
    gender = models.BooleanField(default=1)
    create_time = models.DateTimeField(auto_now_add=True, null=True)
    operate_time = models.DateTimeField(auto_now=True, null=True)
    chinese = models.DecimalField(max_digits=3, decimal_places=1, null=True)
    math = models.DecimalField(max_digits=3, decimal_places=1, null=True)

    # 指定学生和班级的关联关系
    g = models.ForeignKey(Grade, null=True)

    class Meta:
        db_table = 'student'


class Grade(models.Model):
    g_name = models.CharField(max_length=10)
    create_time = models.DateTimeField(auto_now_add=True)

    class Meta:
        db_table = 'grade'  

3.正向查询

def sel_grade_by_stu(request):
    stu = Student.objects.filter(name='王大锤').first()
    grade = stu.g
    name = grade.g_name

    return HttpResponse(name)

4.反向查询

def sel_stu_by_grade(request):
   grade = Grade.objects.filter(g_name='Java').first()
   stus = grade.student_set.all()
   names = []
   for stu in stus:
       names.append(stu.name)

   return HttpResponse(names)

三、多对多模型

1.多对多模型关系:ManyToManyField()
ManyToManyField字段定义在关联的任何一个模型中都可以

class A:
    name = CharField()

class B:
    a1 = ManyToManyField(A)

正向查询:已知B的对象b,查询A对象:b.a1
反向查询:已知A的对象a,查询B对象:a.b_set
2.定义多对多模型关系

class Student(models.Model):
    name = models.CharField(max_length=10, unique=True)
    age = models.IntegerField(default=18)
    gender = models.BooleanField(default=1)
    create_time = models.DateTimeField(auto_now_add=True, null=True)
    operate_time = models.DateTimeField(auto_now=True, null=True)
    chinese = models.DecimalField(max_digits=3, decimal_places=1, null=True)
    math = models.DecimalField(max_digits=3, decimal_places=1, null=True)

    g = models.ForeignKey(Grade, null=True)

    class Meta:
        db_table = 'student'


class Course(models.Model):
    c_name = models.CharField(max_length=10)

    stu = models.ManyToManyField(Student)

    class Meta:
        db_table = 'course'

3.添加模型关系
添加学生和课程的关系

def stu_course(request):
    stu = Student.objects.get(name='小明')
    course = Course.objects.get(c_name='线代')
    # 给小明添加课程
    # stu.course_set.add(course)

    return HttpResponse('添加课程成功!')

4.删除模型关系
删除学生和课程的关系

def stu_course(request):
    stu = Student.objects.get(name='小明')
    course = Course.objects.get(c_name='线代')
    # 删除小明的课程
    # stu.course_set.remove(course)

     return HttpResponse('删除课程成功!')

四、引入模板

1.在当前项目新建templates文件夹
2.修改setting.py配置文件
'DIRS': [os.path.join(BASE_DIR, 'templates')];

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

3.渲染页面

def index(request):
    stus = Student.objects.all()

    return render(request, 'index.html', {'students': stus})

五、模板标签

1.解析变量

{{ 变量 }}

2.for表达式

# 格式1:
    {% for 变量 in 列表 %}

    {% endfor %}

# 格式2:
    {% for 变量 in 列表 %}

    {% empty %}

    {% endfor %}
#注意:当列表为空或者不存在时,执行empty之后的语句

forloop的用法:

{{ forloop.counter }} 表示当前是第几次循环,从1开始
{{ forloop.counter0 }} 表示当前从第几次循环,从0开始
{{forloop.revcounter}}逆序表示当前是第几次循环,到1停
{{forloop.revcounter0}}逆序表示当前是第几次循环,到0停
{{forloop.first}}是否是第一个      布尔值:True/False
{{forloop.last}}是否是最后一个      布尔值:True/False

3.if表达式

# 格式1:
    {% if 表达式 %}

    {%  endif %}

# 格式2:
    {% if 表达式 %}

    {% else %}

    {% endif %}

# 格式3:
    {% if 表达式 %}

    {% elif 表达式 %}

    {% else %}

    {% endif %}

4.ifequal判断相等

{% ifequal value1 value2 %}

{% endifequal %}

5.extends模板继承
extends继承,写在开头位置

{% extends '父模板路径' %}

6.block模板挖坑

{% block 关键字 %}

{% endblock %}

7.load static加载静态文件

{% load static %}

8.comment注释
多行注释,注释不可见且不可运行

{% comment %}
    注释内容
{% endcomment %}

六、模板注释

1.
单行注释,可见并且可运行

<!-- 注释内容 -->

2.{# #}单行注释
单行注释,页面源码中不会显示注释内容并且不可执行

{# 注释内容 #}

3.{% comment %}
多行注释,注释不可见且不可运行

{% comment %}
    注释内容
{% endcomment %}

七、继承模板

1.base.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>
        {% block title %}
        {% endblock %}
    </title>
    {% block css %}
    {% endblock %}

    {% block js %}
    {% endblock %}
</head>
<body>
    {% block content %}
    {% endblock %}
</body>
</html>

2.base_main.html

{% extends 'base.html' %}

{% block js %}
    <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
{% endblock %}

八、填充模板

1.动态填充

{% extends 'base_main.html' %}

{% block title %}
    index
{% endblock %}

{% block content %}
    <p>我是首页</p>
    <table>
        <thead>
            <th>编号</th>
            <th>id</th>
            <th>姓名</th>
            <th>年龄</th>
            <th>班级</th>
        </thead>
        <tbody>
            {% for stu in students %}
            <tr>
                <td>{{ forloop.counter }}</td>
                <td>{{ stu.id }}</td>
                <td {% if forloop.counter == 1 %} style="color:red;" {% endif %}>
                    {{ stu.name }}
                </td>
                <td {% ifequal forloop.counter 1 %} style="font-size:10px" {% endifequal %}>
                    {{ stu.age }}
                </td>
                <td>{{ stu.g.g_name }}</td>
            </tr>
            {% endfor %}
        </tbody>
    </table>
{% endblock %}

2.静态填充
静态加载:STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]

{% extends 'base_main.html' %}

{% block title %}
    index
{% endblock %}

{% block css %}
    <!--  直接定义静态配置 -->
    <!--<link href="/static/css/index.css" rel="stylesheet">-->

    <!-- 加载渲染静态配置文件 -->
    {% load static %}
    <link href="{% static 'css/index.css' %}" rel="stylesheet">
{% endblock %}

{% block js %}
    <!--  重写父类块 -->
    {{ block.super }}
    <script src=""></script>
{% endblock %}

{% block content %}
    <p>我是首页</p>
{% endblock %}

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

推荐阅读更多精彩内容

  • Django 1.8.2 文档Home | Table of contents | Index | Modules...
    轩辕小爱阅读 2,343评论 0 2
  • 模块间联系越多,其耦合性越强,同时表明其独立性越差( 降低耦合性,可以提高其独立性)。软件设计中通常用耦合度和内聚...
    riverstation阅读 2,057评论 0 8
  • Django 准备 “虚拟环境为什么需要虚拟环境:到目前位置,我们所有的第三方包安装都是直接通过 pip inst...
    33jubi阅读 1,313评论 0 5
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,566评论 18 139
  • 昨夜失眠,凌晨四点入睡,早起看见这句子,着实被惊醒。你眼中的享受是什么?做到怎样才能停下来去享受呢? ...
    大耳朵蘑菇阅读 519评论 0 0