3、Django_模板、CSRF、request、render、抛出404错误、URL转换器、Json响应

一、模板
  • 什么是模板?
    在MVT模式中,T/Template就是模板,负责封装和生成要返回的html。
  • 例子:创建一个模板html,浏览器请求url,则返回该html返回到浏览器
    1.在templates创建index.html文件
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Django的第一个应用</title>
</head>
<body>
    <h2>首页</h2>
</body>
</html>

2.修改之前polls/views.py的内容,Index请求类的get方法的返回值改为上面创建好的index.html

class Index(View):
    """
    类视图,需继承View类
    """

    def get(self, request):
        # render(request对象,读取html文件并返回给浏览器)
        return render(request, 'index.html')

    def post(self, request):
        return HttpResponse("hello, django.  You're at the polls index.==>POST")

结果:
模板
二、Django接收参数request

有些好奇,当发送请求给Django的View后,View接受到的request对象是什么内容,参数又是什么样子的

request.GET:返回一个类似字典的内容,其中第一个one=1没有显示,但是实际好像接受了,通过request. GET.getlist(key)能看到

request.GET

request.GET.get(key):可获取到对应的value,如果有多个相同key,则获取到的是最后一个value。因为字典中key是唯一的,但是实际上貌似全部都接收了。

request.GET.get(key)

request. GET.getlist(key):可获得所有相同key的value,返回列表。有两个one的键值对:

request. GET.getlist('one')

  • post请求,发送form表单

    坑位:发送post请求403,然后响应内容是:
    CSRF

解决方法:
1.到settings.py注释下面这行(不推荐)

解决CSRF

2.解决cookie没有csrf_token的问题
前端form表单所在的html中添加{{ csrf_token }},这样请求时就会携带上csrf_token给服务端


使用postman发送带form表单的post请求(form-data):
POST

request.POST来获取form表单的内容,结果和GET类似:

post-form

也可以使用request.POST.get(key)request.POST.getlist(key),其结果和get的一样

request.POST.get(key)

request.POST.getlist(key)

  • 使用postman发送带有json格式参数的post请求:
    post-json

    通过request.body可看到:
    request.body

    decode一下:
    decode
三、render
  • 一个render函数会返回一个经过字典数据渲染后的模板封装而成的HttpResponse对象
  • render(request, 模板html、传给模板html的字典数据)
    参数:
    1.request:请求对象,就是view函数的第一个参数
    2.模板html:模板所对应的html文件
    3.字典数据:该数据会传递给第二个参数中的html文件
  • 例子:
from django.shortcuts import render
from .models import Question

def index(request):
    latest_question_list = Question.objects.order_by('-pub_date')[:5]
    context = {'latest_question_list': latest_question_list}
    return render(request, 'polls/index.html', context)
四、抛出404错误

如果访问的资源不存在的话,我们想抛出404错误,而不是暴露Django的错误信息。Django为我们提供了这样一个方法

  • get_object_or_404():将一个Django模型作为第一个位置参数,后面可以跟上任意个数的关键字参数,如果对象不存在则弹出Http404错误。

  • 为什么我们使用辅助函数get_object_or_404()而不是自己捕获ObjectDoesNotExist异常呢?还有,为什么模型API不直接抛出ObjectDoesNotExist而是抛出Http404呢?
    因为这样做会增加模型层和视图层的耦合性。而Django的设计思想中,最重要的思想之一就是要保证松散耦合。一些受控的耦合将会被包含在 django.shortcuts模块中。

  • 例子:当id不存在时,抛出404

from django.shortcuts import get_object_or_404, render

from .models import Question
# ...
def detail(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    return render(request, 'polls/detail.html', {'question': question})
  • 还有一个get_list_or_404()方法
    get_object_or_404()类似,只不过是用来替代filter()函数,当查询列表为空时弹出404错误。(filter()是模型API中用来过滤查询结果的函数,它的结果是一个列表集。而get则是查询一个结果的方法,和filter是一个和多个的区别)

  • 当然,因为自带的404等页面太丑,一般都是自定义404、500等页面


1.urls.py

from django.contrib import admin
from django.urls import path
from app import views

urlpatterns = [
    path('admin/', admin.site.urls),
]

# 增加的条目
handler400 = views.bad_request
handler403 = views.permission_denied
handler404 = views.page_not_found
handler500 = views.error

2.在应用/views.py文件增加对应的处理视图:

def bad_request(request):
    return render(request, '400.html')

def permission_denied(request):
    return render(request, '403.html')

def page_not_found(request):
    return render(request, '404.html')

def error(request):
    return render(request, '500.html')

3.在对应位置创建400.html等页面文件即可

五、url转换器

在项目中,有事件需要前端传递特定类型的参数过来,比如说int。那么此时就需要用到Django内置的url转换器,它可以把传递过来的参数转换成指定的类型

  • 首先看下源码
    from django.urls import converters,进入converters类,可看到提供了5种可转换类型:

    URL转换器类型

  • IntConverter():可传递任意整数
    1.[0-9]整形数字
    2.+一个或多个

    IntConverter

  • PathConverter():可传递任意字符串、符号等
    1..:任意字符
    2.+:一个或多个

    PathConverter

  • SlugConverter()
    1.'[-a-zA-Z0-9_]+':由-a-zA-Z0-9_中的一个或多个组成的字符串

    SlugConverter

  • StringConverter():默认的转换器
    1.[^/]+:除了/之外的都可以

    StringConverter

  • UUIDConverter()
    1.[0-9a-f]:表示只能是0到9之间的任意整形数字和a-f 之间的字母
    2.{8}:表示只能有8个这样的字母或者数字。
    3.-即指定了这个字符,必须使用它,整个字符窜的意思就是8个[0-9a-f],后面用一个-连接
    4.后面的以此类推

  • 总结
    'int': IntConverter():一个或多个整数(0-9)
    'path': PathConverter():所有字符串
    'slug': SlugConverter():英文中的横杆或者英文字符或者阿拉伯数字或者下划线
    'str': StringConverter()除了斜杠/以外的所有字符
    'uuid': UUIDConverter():只有满足uuid形式的字符串

  • 例子
    1.在polls/views.py添加一个视图方法,用于接收id参数并返回

from django.http import HttpResponse
from django.views import View

class Index(View):
    """
    类视图,需继承View类
    """
def get_id(request, id):
    return HttpResponse(F'id是{id}')

2.在polls/urls.py添加对应的映射

urlpatterns = [
    path(r'get_id/<int:id>', views.get_id, name='get_id')
]

3.访问http://localhost:8000/polls/get_id/3

get_id/3

如果参数不是整数,传递过去后无法转换成int类型,则会404,比如访问http://localhost:8000/polls/get_id/3.2

get_id/3.2

五、响应json内容

响应字符串、响应模板都试过了,那么是否可以响应json数据呢?这时候就需要用到JsonResponse
PS.JsonResponse第一个参数默认必须为dict,如果不想如此,需要设置safe=false,则为return JsonResponse(value, safe = false)
1.polls/views.py添加代码:

# Create your views here.
from django.http import JsonResponse

def response_json(request):
    # 响应json内容
    return JsonResponse(
        {
            "name": "lzl",
            "gender": "man"
        }
    )
  1. polls/urls.py添加映射
path('json', views.response_json)

3.访问http://localhost:8000/polls/json
4.结果:

polls/json

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

推荐阅读更多精彩内容