Django 4 笔记 - 2.视图

使用模板渲染页面

  1. bicycle 目录下创建 templates 子目录,并在其中创建两个模板文件:base.htmlbicycle.html
<!--base.html-->
<!DOCTYPE html>
<html>
<head>
<title>{% block title %}{% endblock %}</title>
</head>
<body>
{% block content %}{% endblock %}
</body>
</html>
<!--bicycle.html-->
{% extends "base.html" %}

{% block title %}My {{ color }} bicycle{% endblock %}

{% block content %}
<h2>This is my <span style="color:{{ color }}">{{ color }}</span> bicycle.</h2>
<pre style="color:{{ color }}; font-family:Courier New">
                                               $"   *.      
               d$$$$$$$P"                  $    J
                   ^$.                     4r  "
                   d"b                    .db
                  P   $                  e" $
         ..ec.. ."     *.              zP   $.zec..
     .^        3*b.     *.           .P" .@"4F      "4
   ."         d"  ^b.    *c        .$"  d"   $         %
  /          P      $.    "c      d"   @     3r         3
 4        .eE........$r===e$$$$eeP    J       *..        b
 $       $$$$$       $   4$$$$$$$     F       d$$$.      4
 $       $$$$$       $   4$$$$$$$     L       *$$$"      4
 4         "      ""3P ===$$$$$$"     3                  P
  *                 $       """        b                J
   ".             .P                    %.             @
     %.         z*"                      ^%.        .r"
        "*==*""                             ^"*==*""
</pre>
{% endblock %}
  1. 修改 bicycle/views.py ,改为返回 TemplateResponse 对象。
from django.template.response import TemplateResponse

def my_bicycle(request):
    context = {'color': 'blue'}
    return TemplateResponse(request, 'bicycle.html', context)

也可以使用 render(),效果一样。

from django.shortcuts import render

def my_bicycle(request):
    context = {'color': 'blue'}
    return render(request, 'bicycle.html', context)
  1. 运行后,访问 http://127.0.0.1:8000/bicycle/ 效果如下:
    在这里插入图片描述
  2. 可以在项目的 settings.py 中对模板系统进行定制,比如修改 DIRS ,不过一般没有必要。
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [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',
            ],
        },
    },
]

接收请求参数

通过 QueryString 传参

修改 bicycle/views.py,从 request.GET 获得 color 参数:

from django.template.response import TemplateResponse

def my_bicycle(request):
    context = {'color': request.GET['color']}
    return TemplateResponse(request, 'bicycle.html', context)

在浏览器中请求 http://127.0.0.1:8000/bicycle/?color=brown ,得到以下页面:
在这里插入图片描述
即使是使用 POST 方法请求上面的 URL,也是一样的结果(尝试前先禁用 django 的 csrf 中间件,关闭 csrf 保护机制):

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    #'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
C:\>curl -X POST http://127.0.0.1:8000/bicycle/?color=brown
<!DOCTYPE html>
<html>
<head>
<title>My brown bicycle</title>
</head>
<body>

<h2>This is my <span style="color:brown">brown</span> bicycle.</h2>
<pre style="color:brown; font-family:Courier New">
                                               $"   *.
               d$$$$$$$P"                  $    J
                   ^$.                     4r  "
                   d"b                    .db
                  P   $                  e" $
         ..ec.. ."     *.              zP   $.zec..
     .^        3*b.     *.           .P" .@"4F      "4
   ."         d"  ^b.    *c        .$"  d"   $         %
  /          P      $.    "c      d"   @     3r         3
 4        .eE........$r===e$$$$eeP    J       *..        b
 $       $$$$$       $   4$$$$$$$     F       d$$$.      4
 $       $$$$$       $   4$$$$$$$     L       *$$$"      4
 4         "      ""3P ===$$$$$$"     3                  P
  *                 $       """        b                J
   ".             .P                    %.             @
     %.         z*"                      ^%.        .r"
        "*==*""                             ^"*==*""
</pre>

</body>
</html>

通过 Body 传参

刚才是通过直接禁用 csrf 中间件来关闭 django 的 csrf 保护机制,但一般不要这么做,最好是用 @csrf_exempt 装饰器来免除对某个视图的保护。这次通过 request.POST 获得传入的参数,将 bicycle/views.py 修改为:

from django.template.response import TemplateResponse
from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
def my_bicycle(request):
    context = {'color': request.POST['color']}
    return TemplateResponse(request, 'bicycle.html', context)

使用 curl 执行 POST 请求:

C:\>curl -X POST http://127.0.0.1:8000/bicycle/ -d "color=green"
<!DOCTYPE html>
<html>
<head>
<title>My green bicycle</title>
</head>
<body>

<h2>This is my <span style="color:green">green</span> bicycle.</h2>
<pre style="color:green; font-family:Courier New">
                                               $"   *.
               d$$$$$$$P"                  $    J
                   ^$.                     4r  "
                   d"b                    .db
                  P   $                  e" $
         ..ec.. ."     *.              zP   $.zec..
     .^        3*b.     *.           .P" .@"4F      "4
   ."         d"  ^b.    *c        .$"  d"   $         %
  /          P      $.    "c      d"   @     3r         3
 4        .eE........$r===e$$$$eeP    J       *..        b
 $       $$$$$       $   4$$$$$$$     F       d$$$.      4
 $       $$$$$       $   4$$$$$$$     L       *$$$"      4
 4         "      ""3P ===$$$$$$"     3                  P
  *                 $       """        b                J
   ".             .P                    %.             @
     %.         z*"                      ^%.        .r"
        "*==*""                             ^"*==*""
</pre>

</body>
</html>

但当使用 PUTDELETEGET 等方法时,request.POST 中就不再包含 body 参数了,更通用的方法是将 request.body 转换为 QueryDict

from django.template.response import TemplateResponse
from django.views.decorators.csrf import csrf_exempt
from django.http import QueryDict

@csrf_exempt
def my_bicycle(request):
    data = QueryDict(request.body)
    context = {'color': data['color']}
    return TemplateResponse(request, 'bicycle.html', context)
C:\>curl -X PUT http://127.0.0.1:8000/bicycle/ -d "color=red"
<!DOCTYPE html>
<html>
<head>
<title>My red bicycle</title>
</head>
<body>

<h2>This is my <span style="color:red">red</span> bicycle.</h2>
<pre style="color:red; font-family:Courier New">
                                               $"   *.
               d$$$$$$$P"                  $    J
                   ^$.                     4r  "
                   d"b                    .db
                  P   $                  e" $
         ..ec.. ."     *.              zP   $.zec..
     .^        3*b.     *.           .P" .@"4F      "4
   ."         d"  ^b.    *c        .$"  d"   $         %
  /          P      $.    "c      d"   @     3r         3
 4        .eE........$r===e$$$$eeP    J       *..        b
 $       $$$$$       $   4$$$$$$$     F       d$$$.      4
 $       $$$$$       $   4$$$$$$$     L       *$$$"      4
 4         "      ""3P ===$$$$$$"     3                  P
  *                 $       """        b                J
   ".             .P                    %.             @
     %.         z*"                      ^%.        .r"
        "*==*""                             ^"*==*""
</pre>

</body>
</html>

通过 URL 传参

采用 RESTful 风格的设计时,更优雅的传参方式是通过 URL 传参,为此需修改 bicycle/urls.py

from django.urls import path
from .views import my_bicycle

urlpatterns = [
    path('<str:color>/', my_bicycle),
]

或者使用正则表达式 re_path

from django.urls import re_path
from .views import my_bicycle

urlpatterns = [
    re_path('(?P<color>[a-z]+)/', my_bicycle),
]

然后修改 bicycle/views.py

from django.template.response import TemplateResponse

def my_bicycle(request, color):
    context = {'color': color}
    return TemplateResponse(request, 'bicycle.html', context)

打开浏览器,访问 http://127.0.0.1:8000/bicycle/pink/ :
在这里插入图片描述


响应 JSON 数据(而非 HTML 页面)

通过自行车 ID 得到自行车的颜色,使用 JsonResponse 可返回 JSON 格式的数据。修改 bicycle/urls.pybicycle/views.py

from django.urls import path
from .views import my_bicycle

urlpatterns = [
    path('<int:id>/', my_bicycle),
]
from django.http import JsonResponse

def my_bicycle(request, id):
    color = {
        1: 'yellow',
        2: 'red',
        3: 'blue'
    }
    
    data = {
        'id': id,
        'color': color[id]
    }
    
    return JsonResponse(data)

使用 curl 发起请求:

C:\>curl -X GET http://127.0.0.1:8000/bicycle/1/
{"id": 1, "color": "yellow"}

Http404

当在程序中抛出 Http404 异常时,Django 会加载一个专门处理 404 错误的视图。默认情况下是视图 django.views.defaults.page_not_found()

from django.http import JsonResponse, Http404

def my_bicycle(request, id):
    color = {
        1: 'yellow',
        2: 'red',
        3: 'blue'
    }
    
    if id < 1 or id > 3:
        raise Http404
    else:
        data = {
            'id': id,
            'color': color[id]
        }
        
        return JsonResponse(data)

基于类的视图

基于类的视图提供另一种将视图实现为 Python 对象而不是函数的方法。它们不能替代基于函数的视图,但与基于函数的视图相比,它们是有某些不同和优势的。

  • Organization of code related to specific HTTP methods (GET, POST, etc.) can be addressed by separate methods instead of conditional branching.
  • Object oriented techniques such as mixins (multiple inheritance) can be used to factor code into reusable components.

例如,对于 GET 请求,返回 HTML页面;对于 POST 请求,返回 JSON 数据。如果使用基于类的视图,则将 bicycle/views.py 修改为:

from django.template.response import TemplateResponse
from django.http import JsonResponse
from django.views import View
from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator

@method_decorator(csrf_exempt, name='dispatch')
class MyBicycle(View):
    color = {
        1: 'yellow',
        2: 'red',
        3: 'blue'
    }

    def get(self, request, id):
        context = {'color': self.color[id]}
        return TemplateResponse(request, 'bicycle.html', context)
    

    def post(self, request, id):
        context = {
            'id': id,
            'color': self.color[id]
        }
        return JsonResponse(context)

同时,需要修改 bicycle/urls.py

from django.urls import path
from .views import MyBicycle

urlpatterns = [
    path('<int:id>/', MyBicycle.as_view()),
]

以上是视图的基本用法,更多详细内容则请查阅文档

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值