day44-Django模型关系和模板

2018-11-29  本文已影响0人  xdxh

一、一对一模型

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 %}

上一篇下一篇

猜你喜欢

热点阅读