【Django】从零开始学Django【2】

五. CBV视图

Django植入了视图类这一功能,该功能封装了视图开发常用的代码,无须编写大量代码即可快速完成数据视图的开发,这种以类的形式实现响应与请求处理称为CBV (Class Base Views)。

1. 数据显示视图

数据显示视图是将后台的数据展示在网页上,数据主要来自模型,一共定义了4个视图类,分别是RedirectView、TemplateView、ListView和DetailView

●RedirectView用于实现HTTP重定向,默认情况下只定义GET请求的处理方法。

●TemplateView是视图类的基础视图,可将数据传递给HTML模板,默认情况下只定义GET请求的处理方法。

●ListView是在TemplateView的基础上将数据以列表显示,通常将某个数据表的数据以列表表示。

●DetailView是在TemplateView的基础上将数据详细显示,通常获取数据表的单条数据。

重定向视图 RedirectView

视图类RedirectView用于实现HTTP重定向功能,即网页跳转功能

下面代码演示:

定义路由的时候,若使用视图类turnTo处理HTTP请求,则需要对视图类turnTo使用as_view()方法,这是对视图类turnTo进行实例化处理

python 复制代码
# index的urls.py
from django.urls import path
from .views import *
urlpatterns = [
    # 定义首页的路由
    path('', index, name='index'),
    path('turnTo', turnTo.as_view(), name='turnTo'),
]
python 复制代码
# index的views.py
from django.shortcuts import render,redirect,reverse
from django.http import HttpResponse,Http404
from django.views.generic.base import RedirectView

def index(request):
    return render(request,'index.html')

class turnTo(RedirectView):
    # 设置属性
    permanent=False  # 状态码为302
    url = None  # 重定向的路由地址
    pattern_name = 'index:index'
    query_string = True

    #重写 get_redirect_url
    def get_redirect_url(self, *args, **kwargs):
        print("This is get_redirect_url")
        return super().get_redirect_url(*args, **kwargs)

    # 重写get
    def get(self,request,*args,**kwargs):
        print(request.META.get('HTTP_USER_AGENT'))
        return super().get(request,*args,**kwargs)
html 复制代码
<!DOCTYPE html>
<html>
<body>
<h3>Hello RedirectView</h3>
<a href="{% url 'index:turnTo' %}?k=1">Toturn</a>

</body>
</html>

基础视图 TemplateView

代码如下:

python 复制代码
# index的views.py
from django.shortcuts import render,redirect,reverse
from django.http import HttpResponse,Http404
from django.views.generic.base import TemplateView

class index(TemplateView):
    template_name = 'index.html'
    template_engine = None
    content_type = None
    extra_context = {'title': 'This is GET'}

    # 重新定义模板上下文的获取方式
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['value'] = 'I am MyDjango'
        return context

    # 定义HTTP 的POST请求的处理方法
    # 参数 request 代表 HTTP 请求信息
    def post(self,request,*args,**kwargs):
        self.extra_context = {'title':'This is POST'}
        context = self.get_context_data(**kwargs)
        return self.render_to_response(context)

get_context_data()方法用于获取模板上下文内容,模板上下文是将视图里的数据传递到模板文件,再由模板引擎将数据转换成HTML网页数据。

自定义POST请求的处理方法,当触发POST请求时,将会重设属性extra_context的值,并调用get_context_data()将属性extra_context重新写入,从而实现动态改变模板上下文的数据内容

●extra_context:为模板文件的上下文(模板变量)设置变量值,可将数据转换成网页数据展示在浏览器上。

●get_context_data():继承并重写视图类TemplateView的类方法,在变量context里新增数据value。

python 复制代码
# index的urls.py
from django.urls import path
from .views import *
urlpatterns = [
    # 定义首页的路由
    path('', index.as_view(), name='index'),

]
html 复制代码
<!DOCTYPE html>
<html>
<body>
<h3>Hello,{{ title }}</h3>
<div>{{ value }}</div>
<br>

<form action="" method="post">
    {% csrf_token %}
    <input type="submit" value="Submit">
</form>

</body>
</html>


列表视图ListView

ListView,该视图类是将数据表的数据以列表的形式显示,常用于数据的查询和展示。

由于视图类ListView需要使用模型对象,因此在MyDjango项目里定义PersonInfo模型,在index的models.py中编写以下代码:

python 复制代码
# index的models.py
from django.db import models
class PersonInfo(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=20)
    age = models.IntegerField()

在数据库里生成相应的数据表:

首先在Pycharm里面连接数据库:

这里以SQL Server为例子:
SQLServer配置教程

数据库连接比较麻烦:

django连接sqlserver:

pip install mssql-django==1.2
pip install pyodbc django-pyodbc-azure

还要配置setting.py:

红色部分自己修改:

在终端输入:

powershell 复制代码
# 根据models.py生成相关的.py文件,该文件用于创建数据表
python manage.py makemigrations

# 创建数据表
python manage.py migrate

然后打开数据库,记得刷新!!!

成功!!!

然后编辑index_personinfo:

当指令执行完成后,Django会默认创建多个数据表,其中数据表index_personinfo对应index的models.py中所定义的PersonInfo类,其余的数据表都是Django内置的功能所生成的,主要用于Admin站点、用户认证和Session会话等功能。

代码如下:

python 复制代码
# index的views.py

from django.views.generic import ListView
from .models import PersonInfo

class index(ListView):
    # 设置模板文件
    template_name = 'index.html'
    # 设置模板外的数据
    extra_context = {'title':'人员信息表'}
    # 查询模型
    queryset = PersonInfo.objects.all()
    # 每页展示一条数据
    paginate_by = 1
    # 若不设置,则上下文默认为personinfo_list
    # context_object_name = 'personinfo'
html 复制代码
<!DOCTYPE html>
<html>
<head>
    <title>{{ title }}</title>
</head>
<body>
<h3>{{ title }}</h3>
<table border="1">
    {% for i in personinfo_list %}
        <tr>
            <th>{{ i.name }}</th>
            <th>{{ i.age }}</th>
        </tr>
    {% endfor %}
</table>
<br>
{% if is_paginated %}
<div class="pagination">
<span class="page-links">
    {% if page_obj.has_previous %}
        <a href="/?page={{ page_obj.previous_page_number }}">上一页</a>
    {% endif %}
    {% if page_obj.has_next %}
        <a href="/?page={{ page_obj.next_page_number }}">下一页</a>
    {% endif %}
<br>
<br>
<span class="page-current">
    第{{ page_obj.number }}页,
    共{{ page_obj.paginator.num_pages }}页。
</span>

</span>

</div>

{% endif %}
</body>
</html>

详细视图DetailView

视图类DetailView的属性pk_url_kwarg和slug_url_kwarg用于确定模型的查询条件;属性slug_field用于确定模型的查询字段;属性query_pk_and_slug用于确定模型主键和其他字段的组合查询。

沿用之前的models,编写以下代码:

python 复制代码
# index的urls.py
from django.urls import path
from .views import *
urlpatterns = [
    # 定义首页的路由
    path('<pk>/<age>.html', index.as_view(), name='index'),

]
python 复制代码
# index的views.py

from django.views.generic import DetailView
from .models import PersonInfo

class index(DetailView):
    # 设置模板文件
    template_name = 'index.html'
    # 设置模板外的数据
    extra_context = {'title':'人员信息表'}
    # 设置模型的查询字段
    slug_field = 'age'
    # 设置路由的变量名,与属性slug_field 实现模型的查询功能
    slug_url_kwarg = 'age'
    pk_url_kwarg = 'pk'
    # 设置查询模型
    model = PersonInfo
    # 属性queryset 可以做简单的查询操作
    queryset = PersonInfo.objects.all()
    # 若不设置则模板上下文默认为'personinfo'
    # context_object_name = 'personinfo'
    # 是否将pk和slug作为查询条件
    query_pk_and_slug = True  #属性query_pk_and_slug用于确定模型主键和其他字段的组合查询
html 复制代码
<!DOCTYPE html>
<html>
<head>
    <title>{{ title }}</title>
</head>
<body>
<h3>{{ title }}</h3>
<table border="1">
  
        <tr>
            <th>{{ personinfo.name }}</th>
            <th>{{ personinfo.age }}</th>
        </tr>
</table>
<br>

</body>
</html>


2. 数据操作视图

数据操作视图有4个视图类,分别是FormView、CreateView、UpdateView和DeleteView

●FormView视图类使用内置的表单功能,通过表单实现数据验证、响应输出等功能,用于显示表单数据。

●CreateView实现模型的数据新增功能,通过内置的表单功能实现数据新增。

●UpdateView实现模型的数据修改功能,通过内置的表单功能实现数据修改。

●DeleteView实现模型的数据删除功能,通过内置的表单功能实现数据删除。

3. 日期筛选视图

日期筛选视图是根据模型里的某个日期字段进行数据筛选,然后将符合结果的数据以一定的形式显示在网页上。简单来说,就是在列表视图ListView或详细视图DetailView的基础上增加日期筛选所实现的视图类。

六. 模板

1. Django模板引擎

Django内置的模板引擎包含模板上下文(亦可称为模板变量)、标签和过滤器

模板上下文

{``{ variable }}表示,variable是上下文的名称,它支持Python所有的数据类型,如字典、列表、元组、字符串、整型或实例化对象等

例如:

html 复制代码
# 假如variable1 = '字符串或整型'
<div>{{ variable1 }}</div>
# 输出"<div>字符串或整型</div>"
# 假如variable2={'name': '字典或实例化对象'}
<div>{{ variable2.name }}</div>
# 输出"<div>字典或实例化对象</div>"
# 假如variable3 = ['元组或列表']
<div>{{ variable3.0 }}</div>
# 输出"<div>元组或列表</div>"

如果视图没有为模板上下文传递数据或者模板上下文的某个属性、索引下标不存在,Django就会将其设为空值

自定义标签

标签是对模板上下文进行控制输出,它是以{% tag%}表示的,其中tag是标签的名称,Django内置了许多模板标签,比如{% if %}(判断标签){% for %}(循环标签){% url %}(路由标签)

例如:

python 复制代码
# for标签,支持嵌套,myList可为列表、元组或某个对象
# item可自定义命名,代表当前循环的数据对象
# {% endfor %}是循环区域终止符,代表这区域的代码由标签for输出
{% for item in myList %}
{{ item }}
{% endfor %}
# if标签,支持嵌套
# 判断条件符与上下文之间使用空格隔开,否则程序会抛出异常
# {% endif %}与{% endfor %}的作用是相同的
{% if name == "Lily" %}
{{ name }}
{% elif name == "Lucy" %}
{{ name }}
{% else %}
{{ name }}
{% endif %}
# url标签
# 生成不带变量的URL地址
<a href="{% url 'index' %}">首页</a>
# 生成带变量的URL地址
<a href="{% url 'page' 1 %}">第1页</a>
# with标签,与Python的with语法的功能相同
# total=number无须空格隔开,否则抛出异常
{% with total=number %}
{{ total }}
{% endwith %}
# load标签,导入静态文件标签库staticfiles
# staticfiles来自settings.py的INSTALLED_APPS
{% load staticfiles %}
# static标签,来自静态文件标签库staticfiles
{% static "css/index.css" %}

for标签的模板说明:

html 复制代码
{% for name in name_list %}
{% if forloop.counter == 1 %}
<span>这是第一次循环</span>
{% elif forloop.last %}
<span>这是最后一次循环</span>
{% else %}
<span>本次循环次数为:{{forloop.counter }}</span>
{% endif %}
{% endfor %}
相关推荐
湫ccc1 小时前
《Python基础》之字符串格式化输出
开发语言·python
mqiqe1 小时前
Python MySQL通过Binlog 获取变更记录 恢复数据
开发语言·python·mysql
AttackingLin2 小时前
2024强网杯--babyheap house of apple2解法
linux·开发语言·python
2401_857610032 小时前
SpringBoot社团管理:安全与维护
spring boot·后端·安全
哭泣的眼泪4082 小时前
解析粗糙度仪在工业制造及材料科学和建筑工程领域的重要性
python·算法·django·virtualenv·pygame
凌冰_2 小时前
IDEA2023 SpringBoot整合MyBatis(三)
spring boot·后端·mybatis
码农飞飞2 小时前
深入理解Rust的模式匹配
开发语言·后端·rust·模式匹配·解构·结构体和枚举
一个小坑货2 小时前
Rust 的简介
开发语言·后端·rust
湫ccc2 小时前
《Python基础》之基本数据类型
开发语言·python
monkey_meng3 小时前
【遵守孤儿规则的External trait pattern】
开发语言·后端·rust