Bootstrap

【Django5】多种视图View

系列文章目录

第一章 Django使用的基础知识
第二章 setting.py文件的配置
第三章 路由的定义与使用
第四章 视图的定义与使用
第五章 二进制文件下载响应
第六章 Http请求&HttpRequest请求类
第七章 会话管理(Cookies&Session)
第八章 文件上传实现
第九章 多种视图view
第十章 Django5模板引擎
第十一章 模型定义与使用
第十二章 ORM执行SQL语句和事务
第十三章 表单定义与使用
第十四章 内置Admin系统
第十五章 内置Auth认证系统



前言

本章内容较多,涉及到了列表、详细、新增、修改、删除视图的内容。为了实现快速开发,Django提供了视图类功能,封装了视图开发常用的代码,这种基于类实现的响应与请求称为CBV ( Class Base Views)。


一、列表视图ListView

我们先介绍列表视图ListView,该视图类可以将数据库表的数据以列表的形式显示到页面,常用于数据的查询和展示。

首先为了得到数据库数据,我们先定义模型,来映射数据库表;

models.py里定义StudentInfo类:

from django.db import models


class StudentInfo(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=20)
    age = models.IntegerField()

    class Meta:
        db_table = "t_student"

然后我们执行:python manage.py makemigrations生成数据库迁移文件

所谓的迁移文件, 是类似模型类的迁移类,主要是描述了数据表结构的类文件;

再执行:python manage.py migrate 执行迁移文件,同步到数据库中

注意:生成的表名默认为:app名_定义的表名,可通过db_table 指明数据库表名。

在这里插入图片描述
我们会看到 数据库t_student自动生成了,并且为数据库添加一些数据。

insert into t_student VALUES(null,'张三1',20);
insert into t_student VALUES(null,'张三2',21);
insert into t_student VALUES(null,'张三3',22);
insert into t_student VALUES(null,'张三4',23);
insert into t_student VALUES(null,'张三5',24);
insert into t_student VALUES(null,'张三6',25);
insert into t_student VALUES(null,'张三7',26);
insert into t_student VALUES(null,'张三8',27);
insert into t_student VALUES(null,'张三9',28);
insert into t_student VALUES(null,'张三10',29);
insert into t_student VALUES(null,'张三11',30);
insert into t_student VALUES(null,'张三12',31);

在这里插入图片描述
要使用 ListView,需要继承它并设置一些属性。以下属性是最常用的:

  • model:指定要使用的模型。

  • template_name:指定要使用的模板名称。

  • context_object_name:指定上下文变量名称,默认为 object_list。

  • paginate_by:指定分页大小。

  • extra_context:设置模型外的数据

在views.py里,我们可以定义List类:

class List(ListView):
    # 定义模板名称,用于渲染学生信息列表页面
    template_name = 'student/list.html'

    # 添加额外的上下文信息,用于在页面中显示标题
    extra_context = {'title': '学生信息列表'}

    # 定义查询集,获取所有学生信息
    # 从StudentInfo模型中获取所有学生信息的查询集
    queryset = StudentInfo.objects.all()

    # 定义上下文对象名称,用于在模板中引用学生信息列表
    context_object_name = 'students_list'

    # 设置分页参数,每页显示5条学生信息
    paginate_by = 5

除了设置属性之外,还可以重写 ListView 中的方法以进行自定义。以下是一些常见的方法:

  • get_queryset():返回要在视图中使用的查询集合。这里可以对查询集合进行筛选、排序等操作。

  • get_context_data():返回要在模板上下文中使用的变量。这里可以添加额外的变量,如表单、过滤器等。

urls.py里,我们定义映射:

path('student/list', helloWorld.views.List.as_view())

在模版页面,Django 给我们提供了分页的功能:Paginator和Page类都是用来做分页的。

# Paginator常用属性和方法
1.`count`: 总共有多少条数据。
2.`num_pages`: 总共有多少页。
3.`page_range`:页面的区间。比如有三页,那么就是```range``(``1``,``4``)`。
# Page常用属性和方法:
1.`has_next`: 是否还有下一页。
2.`has_previous`: 是否还有上一页。
3.`next_page_number`: 下一页的页码。
4.`previous_page_number`: 上一页的页码。
5.`number`: 当前页。
6.`start_index`: 当前页的第一条数据的索引值。
7.`end_index`: 当前页的最后一条数据的索引值。

我们在templates下新建student目录,再新建list.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{{ title }}</title>
</head>
<body>
<h3>{{ title }}</h3>
<table border="1">
    <tr>
        <th>编号</th>
        <th>姓名</th>
        <th>年龄</th>
    </tr>
    {% for student in students_list %}
    <tr>
        <td>{{ student.id }}</td>
        <td>{{ student.name }}</td>
        <td>{{ student.age }}</td>
    </tr>
    {% endfor %}
</table>
<br>
{% if is_paginated %}
    {% if page_obj.has_previous %}
    <a href="/student/list?page={{ page_obj.previous_page_number }}">上一页</a>
    {% else %}
    <a>上一页</a>
        
    {% endif %}
      {% for current in paginator.page_range %}
        {% if current == page_obj.number %}
            <a><b><font color="black">{{ current }}</font></b></a>
        {% else %}
            <a href="/student/list?page={{ current }}">{{ current }}</a>
        {% endif %}
    {% endfor %}
    
    {% if page_obj.has_next %}
    <a href="/student/list?page={{ page_obj.next_page_number }}"> 下一页</a>
    {% else %}
    <a>下一页</a>
    {% endif %}
{% endif %}
</body>
</html>

运行测试

测试,浏览器输入:http://127.0.0.1:8000/student/list
在这里插入图片描述
点击下一页:
在这里插入图片描述

二、详细视图DetailView

DetailView多用于展示某一个具体数据对象的详细信息的页面。

使用DetailView,你只需要指定要使用的模型和对象的唯一标识符,并可以自定义其他一些属性,例如模型名称、模板名称、上下文数据等。

以下是DetailView的一些常见属性和方法:

  • model:指定要使用的模型。

  • queryset:指定要使用的查询集,用于获取对象。如果未指定,则将使用模型的默认查询集。

  • pk_url_kwarg:指定URL中用于获取对象的唯一标识符的参数名称,默认为’pk’。

  • context_object_name:指定将对象传递给模板时的上下文变量名称,默认为’model’。

  • template_name:指定要使用的模板的名称。

  • get_object(queryset=None):获取要展示的对象。可以重写这个方法来自定义获取对象的逻辑。

  • get_context_data(kwargs):返回要传递给模板的上下文数据。你可以重写这个方法来自定义上下文数据。

  • get():处理GET请求的方法,根据配置的对象获取规则执行对象获取和展示逻辑。

  • dispatch(request, *args, **kwargs):处理请求的入口方法,根据请求的不同方法(GET、POST等)执行相应的处理逻辑。

通过继承DetailView,并根据自己的需求重写这些方法,你可以创建自定义的展示单个对象详细信息的视图,并实现你想要的功能。

总之,DetailView是Django框架中的一个便捷的通用视图,用于展示单个对象的详细信息,并提供了一些有用的属性和方法来简化对象展示逻辑。

通过重新设置model属性来指定需要获取的Model类,默认对象名称为object,也可以通过重新设置context_object_name属性来更改这个名字。

下面我们通过实例来体验下吧:

views.py里新建Detail,继承DetailView

class Detail(DetailView):
    # 模板文件名,用于渲染学生信息详情页面
    template_name = 'student/detail.html'
    
    # 添加到模板上下文的额外数据,用于在页面中显示标题
    extra_context = {'title': '学生信息详情'}
    
    # 指定模型类,本页面处理的对象是StudentInfo类的实例
    model = StudentInfo
    
    # 指定模板中使用的对象名称,使得在模板中可以通过这个名称访问对象
    context_object_name = 'student'
    
    # 指定用于获取学生唯一标识的URL参数名称,默认为'pk'
    # pk_url_kwarg = 'id'


templates下的student目录下新建detail.html文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{{ title }}</title>
</head>
<body>
<h3>{{ title }}</h3>
编号:{{ student.id }}<br/>
姓名:{{ student.name }}<br/>
年龄:{{ student.age }}
</body>
</html>

urls.py里加一个映射:

    path('student/detail/<int:pk>',helloWorld.views.Detail.as_view())

list.html里,加一个操作项-查看详情:
在这里插入图片描述

运行测试

http://127.0.0.1:8000/student/list,点击查看详情
在这里插入图片描述
在这里插入图片描述

三、新增视图CreateView

视图类CreateView是对模型新增数据的视图类,它是在表单视图类FormView 的基础上加以封装的。简单来说,就是在视图类FormView的基础上加入数据新增的功能。

所有涉及到表单视图的功能开发,都需要定义form表单类:

我们新建forms.py,里面新建StudentForm

from django import forms
from django.forms import ModelForm

from helloWorld.models import StudentInfo


class StudentForm(ModelForm):
    """
    学生信息表单类,用于创建和验证学生信息表单。
    继承自django.forms.ModelForm,针对StudentInfo模型进行了表单字段和样式的自定义。
    """

    class Meta:
        """
        学生信息表单的元数据类,用于配置表单的模型、字段和小部件。
        """

        model = StudentInfo # 导入model
        # fields = '__all__' # 代表所有字段

        fields = ['name', 'age']  # 指定字段
        """
        指定表单应包含的字段列表。这里只包括了'name'和'age'两个字段。
        """

        widgets = {
            'name': forms.TextInput(attrs={'id': 'name', 'class': 'form-control'}),
            'age': forms.NumberInput(attrs={'id': 'age', 'class': 'form-control'})
        }
        """
        对表单字段的小部件进行自定义,设置输入框的HTML属性,以美化表单呈现。
        """

        labels = {
            'name': '姓名',
            'age': '年龄'
        }
        """
        自定义表单字段的标签,用于改善表单的可读性和用户体验。
        """

views.py里新建Create类,继承CreateView

class Create(CreateView):
    # 模板文件名,用于渲染创建学生信息的页面
    template_name = 'student/create.html'
    # 添加到模板上下文的额外数据,用于在页面中显示标题
    extra_context = {'title': '创建学生信息'}
    # 指定form
    form_class = StudentForm
    # 执行成功后跳转地址
    success_url = '/student/list'

student目录下新建create.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{{ title }}</title>
    
    <style>
        .form-control {
            width: 50px;
        }
    </style>
</head>
<h3>{{ title }}</h3>
<body>
<form method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <input type="submit" value="提交">
</form>
</body>
</html>


urls.py里加一个映射:

    path('student/create', helloWorld.views.Create.as_view()),


list.html页面,加一个新增学生链接
在这里插入图片描述

运行测试

访问http://127.0.0.1:8000/student/list

在这里插入图片描述
点击增加学生,即可跳转到http://127.0.0.1:8000/student/create
在这里插入图片描述
点击提交后,会跳转到list页面,并查看数据是否提交成功
在这里插入图片描述

可以看到,数据提交成功了。

四、修改视图UpdateView

视图类UpdateView是在视图类FormView和视图类DetailView的基础上实现的,它首先使用视图类 DetailView的功能(功能核心类是SingleObjectMixin),通过路由变量查询数据表某条数据并显示在网页上,然后在视图类FormView的基础上,通过表单方式实现数据修改。

views.py里新建Update类:

class Update(UpdateView):
    # 模板文件名,用于渲染创建学生信息的页面
    template_name = 'student/update.html'
    # 添加到模板上下文的额外数据,用于在页面中显示标题
    extra_context = {'title': '修改学生信息'}
    # 指定模型类,本页面处理的对象是StudentInfo类的实例
    model = StudentInfo
    # 指定form
    form_class = StudentForm
    # 执行成功后跳转地址
    success_url = '/student/list'


student下新建update.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{{ title }}</title>
    
    <style>
        .form-control {
            width: 50px;
        }
    </style>
</head>
<h3>{{ title }}</h3>
<body>
<form method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <input type="submit" value="提交">
</form>
</body>
</html>


urls.py里加一个映射:

path('student/update/<int:pk>', helloWorld.views.Update.as_view()),


list.html里加一个
在这里插入图片描述

运行测试

浏览器输入 http://127.0.0.1:8000/student/list
在这里插入图片描述
点击修改后,跳转到修改页面,然后修改数据并提交。
在这里插入图片描述

提交完成后可以看到,数据已经被修改了
在这里插入图片描述

五、删除视图DeleteView

视图类DeleteView的使用方法与视图类UpdateView类似,视图类DeleteView只能删除单条数据,路由变量为模型主键提供查询范围,因为模型主键具有唯一性,所以通过主键查询能精准到某条数据。查询出来的数据通过POST 请求实现数据删除。

views.py里面,我们新建Delete类,继承DeleteView

class Delete(DeleteView):
    # 模板文件名,用于渲染创建学生信息的页面
    template_name = 'student/delete.html'
    # 添加到模板上下文的额外数据,用于在页面中显示标题
    extra_context = {'title': '删除学生信息'}
    # 指定模型类,本页面处理的对象是StudentInfo类的实例
    model = StudentInfo
    # 指定模板中使用的对象名称,使得在模板中可以通过这个名称访问对象
    context_object_name = 'student'
    # 执行成功后跳转地址
    success_url = '/student/list'

urls.py里加下映射:

   path('student/delete/<int:pk>', helloWorld.views.Delete.as_view()),

在student文件下添加delete.html文件

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

</head>
<h3>{{ title }}</h3>
<body>
<form method="post">
    {% csrf_token %}
    <a>你确认要删除编号为{{ student.id }},姓名为{{ student.name }},年龄为{{ student.age }}的学生吗?</a>
    <input type="submit" value="确认">
</form>
</body>
</html>

在list中加一条
在这里插入图片描述

运行测试

访问http://127.0.0.1:8000/student/list?page=3,点击删除编号为18的学生数据
在这里插入图片描述

页面跳转到确认删除页面
在这里插入图片描述
点击确认后自动跳转到页表页面,查看数据是否删除
在这里插入图片描述

总结

本章介绍了很多视图的基础功能,django中自带封装好的视图能大大减少开发的工作量,具体内容后续实战的时候再说。

;