ジャンゴ(XVI)ケースベースのログインテンプレート:ログデコレータ、CSRF攻撃と防御、CSRF Ajaxの開口部のポスト文言は、確認コードを生成し、看板にコードを追加し、逆分解能質量参加+

、CSRF攻撃

1.1 CSRF攻撃(CSRF)

[すなわち] CSRF攻撃:サードパーティのサイトには、直接、またはあなたのセッションクッキーを介して変更することができ、第三者のウェブサイトを通じて、リクエストフォージェリは、(あなたは、通常のサイトをログに記録し、セッションCookieまたはログイン情報を保存し、撤回されていないことを条件とします)ユーザ名・パスワード通常のウェブサイト。
ここに画像を挿入説明

  1. まず、ユーザーは、ユーザー名とパスワードを入力し、ジャンプが成功し、パスワードのページを変更した後にログオンできるように、ログインページを行います。[パスワードの変更]ページで、新しいパスワードを入力し、パスワードの変更を完了するために、[OK]ボタンをクリックしてください。
  2. ログオンページでは、テンプレートファイルlogin.htmlとが必要です。パスワード変更ページもテンプレートファイルchange_pwd.htmlが必要です。
  3. ビューの表示ログインログインページ、ビューlogin_checkを確認するには、ビューchange_pwd_actionを扱うパスワードを変更し、表示ビューchange_pwdページを投稿するにはログイン。
  4. その他の機能:
    A)は、ユーザーがログオンした後にのみ、暗号化操作を変更することができます。
  5. ログインデコレータ機能(APP2 / views.py):
def login_required(view_func): #参数即调用它的函数
    '''登录判断装饰器'''
    def wrapper(request, *view_args, **view_kwargs): # 内部函数,包装一下
        # 判断用户是否登录
        if request.session.has_key('islogin'): #如果登录了,就返回真正页面(调用此装饰器函数的函数)
            # 用户已登录,调用对应的视图
            return view_func(request, *view_args, **view_kwargs)
        else:
            # 否则,用户未登录,则跳转到登录页
            return redirect('/login')
    return wrapper
  1. なページとして装飾呼び出しは、操作にログインし、またはログインページにジャンプする必要がありますログイン
    [APP2 / views.py]@login_required
# /change_pwd
@login_required #作用:把此页面作为一个参数传到login_required里
def change_pwd(request):
    '''显示修改密码页面'''
    return render(request, 'booktest/change_pwd.html')

[例](ポスト操作にログインする必要があります)パスワードを変更するにはCSRF攻撃:

1)のProject2 / settings.pyコメント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',
]

2)テンプレート/ change_pwd.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>修改密码页面</title>
</head>
<body>
<form method="post" action="/change_pwd_action/">
    新密码:<input type="password" name="pwd">
    <input type="submit" value="确认修改">
</form>
</body>
</html>

3)APP2 / views.py [ログインデコレータ]

[1]ログインはデコレータ:ユーザーは、対応するビューの呼び出し、ログインしている、ユーザーがログインページへのジャンプ、ログインしていない
[2]ページのデコレータでコールログを操作するにはログインする必要があり
、[3]にログインする必要があり、ページの装飾上のコールログを操作しますデバイス

from django.shortcuts import render,redirect
from django.template import loader,RequestContext
from django.http import HttpResponse,JsonResponse
from app2.models import BookInfo

def login(request):
    '''登录页'''
    # 判断用户是否登录,用户已登录, 直接跳转到图书列表
    if request.session.has_key('islogin'):
        return redirect('/change_pwd/')
    else:
        #如果用户名密码已经在cookie中,则取到它,并做为参数返回给渲染页面
        if 'username' in request.COOKIES:
            #获取cookie中的用户名、密码
            username=request.COOKIES['username']
            #password=request.COOKIES['password']

        else:
            username=''
            password=''
    return render(request,'app2/login.html',{'username':username,'password':password})


def login_check(request):
    '''登录校验'''
    #1.获取用户名密码
    username=request.POST.get('username')
    password=request.POST.get('password')
    remember=request.POST.get('remember') #接收remeber
    #2.进行校验,并返回json数据
    if username=='jim' and password=='123':
        #return redirect('/books')
        response = JsonResponse({'res':1}) #正确返回1,重写

        #如果remember==on,则把用户名,密码设置cookie到cookie
        if remember=='on':
            #response.set_cookie('username',username,max_age=7*24*3600)
            #response.set_cookie('password',password,max_age=7*24*3600)
            # 记住用户登录状态把用户名设置到session
            request.session['username'] = username
            # 返回应答
            # 如果用户勾选了remember的条件下,设置session,记住用户登录状态
            request.session['islogin'] = True # 只有session中有islogin,就认为用户已登录
        return response #不要忘记返回response
    else:
        #return redirect('/login')
        return JsonResponse({'res':0}) #错误返回0

#【1】登录装饰器:用户已登录,调用对应的视图;用户未登录,跳转到登录页
def login_required(view_func):
    '''登录判断装饰器'''
    def wrapper(request, *view_args, **view_kwargs):
        # 判断用户是否登录
        if request.session.has_key('islogin'):
            # 用户已登录,调用对应的视图
            return view_func(request, *view_args, **view_kwargs)
        else:
            # 用户未登录,跳转到登录页
            return redirect('/login')
    return wrapper


# /change_pwd
@login_required #【2】需要登录才能操作的页面调用登录装饰器
def change_pwd(request):
    '''显示修改密码页面'''
    # # 进行用户是否登录的判断
    # if not request.session.has_key('islogin'):
    #     # 用户未登录,跳转到登录
    #     return redirect('/login')

    return render(request, 'app2/change_pwd.html')


# /change_pwd_action
@login_required #【3】需要登录才能操作的页面调用登录装饰器
def change_pwd_action(request):
    '''模拟修改密码处理'''
    # # 进行用户是否登录的判断
    # if not request.session.has_key('islogin'):
    #     # 用户未登录,跳转到登录
    #     return redirect('/login')

    # 1.获取新密码
    pwd = request.POST.get('pwd')
    # 获取用户名
    username = request.session.get('username')
    # 2.实际开发的时候: 修改对应数据库中的内容...
    # 3.返回一个应答
    return HttpResponse('%s修改密码为:%s'%(username,pwd))

4)APP2 / urls.py

    path('login/',views.login),#登录页
    path('login_check',views.login_check),#登录检测
    
    path('change_pwd/', views.change_pwd), # 修改密码页面显示
    path('change_pwd_action/', views.change_pwd_action), # 修改密码处理

5)テンプレート/ login.htmlと(Ajaxのログイン・テクノロジー)

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <!-- 【0】引入jquery -->
    <script src="/static/js/jquery-1.12.4.min.js"></script>
    <title>登录页面</title>
</head>
<script>
    // 写ajax处理函数
    $(function () {
        $('#btnLogin').click(function () {
            //1.获取用户名、密码、是否记住用户名
            username=$('#username').val()
            password=$('#password').val()
            remember=$('#remember').val() //【2】是否记住用户名
            //2.发起ajax--post(username,password)请求验证,地址:/login_check
            $.ajax({
                'url':'/login_check',//验证地址
                'type':'post',//请求类型
                'data':{'username':username,'password':password,'remember':remember},//【3】发送数据,加上remember
                'dataType':'json',//希望返回数据类型
            }).success(function(data){
                //成功返回{'res':1},失败{'res':0}
                if(data.res===0){
                    $('#msg').show().html('用户名或密码错误请重试!')//登录失败则显示msg,并在里写入信息
                }else{//成功跳转到books页面
                    location.href='/change_pwd'
                }
            })

        })
    })
</script>
<style>
    /* 信息提示样式 */
#msg{
    display: none;
    color:red;
}
</style>
<body>
    <!-- 原form删除,input的name变id,方便jquery操作 -->
    <!-- 【4】把views页的login()函数传过来的用户名,密码赋值给对应处 -->
    用户名:<input type="text" id="username" value="{{username}}"><br/>
    密码:<input type="password" id="password" value="{{password}}"><br/>
    <!-- 加入一个信息提示框,用于密码等错误提示 -->
    <div id="msg"></div>
    <!-- 【1】记住用户名,设置cookie用,如果勾选则其value=on -->
    <input type="checkbox" id="remember">记住用户名<br/>
    <!-- 按钮type改button,加一个id方便jquery操作 -->
    <input type="button" id="btnLogin" value="登录">

</body>
</html>

6)の効果:のhttp://127.0.0.1:8000 /ログイン/を

ユーザー名やパスワードエラー:

ここに画像を挿入説明

ページをログインせずにパスワードを変更するには直接アクセスします。http://127.0.0.1:8000 / change_pwdジャンプバックログインページへ
U / Pを正しく(ジム、123)移動:のhttp://127.0.0.1:8000 / change_pwd

ここに画像を挿入説明
その後ヒント:次のようにジム・変更パスワード:456

7)の変更手順は、サードパーティのWebサイトを経由して、特定のコードを次に示します。

  1. サーバーのLAN IPおよびパブリックIPにアクセスするための最初のチェック
ipconfig /all
找到:
192.168.1.4

公网直接百度IP,查看即可
  1. サービスを作成し、以下の2対1
如果在局域网创建服务:
py manage.py runserver 192.168.1.4:8000

如果在【虚拟机】或【真正服务器】创建服务:
py manage.py runserver 公网IP:8000
  1. 設定settings.py
DEBUG = False #True
ALLOWED_HOSTS = ['*']
  1. 192.168.1.4:アクセスLANに別のコンピュータにアクセスするために8000 /ログインサイト、(、123ジム)ログインに成功すると入力します。
  2. :自己偽のページには、次のページでは、コンピュータへのアクセスに[作成]
    [CSRF-test.htmlというを]
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>修改密码页面</title>
</head>
<body>
<form method="post" action="http://192.168.1.4:8000/change_pwd_action/">
    <input type="hidden" name="pwd" value='789'><!--【1】用了隐藏input,页面只能看到一个按钮,并给新密码定为789-->
    <input type="submit" value="点我有惊喜!">
</form>
</body>
</html>
  1. ステップ5のページを開き、対応するWebサイトの成功へのキーポイントは、パスワードを変更するには:
    ここに画像を挿入説明
  2. クロスサイトリクエストフォージェリのポストは、ユーザーパスワードの成功を修正します!
jim修改密码为:789

1.1.1 DjangoはCSRFの道を防ぎます:

1)デフォルトのCSRFミドルウェアによって(のProject2 / settings.py)。

[1]ジャンゴCSRF保護はデフォルトでオンになって、それが後の提出のためにのみ有効です

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware', #【1】django默认打开csrf防护,它只对post提交有效
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

2)を加えた後、フォームデータ送信する際に{% csrf_token %}タグを

(この例では、テンプレートに対応:change_pwd.html)。
[注]:必要提出後のページのページが追加する必要があり{% csrf_token %}、さらには、サイトのページを参照してくださいに失敗します。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>修改密码页面</title>
</head>
<body>
<form method="post" action="/change_pwd_action/">
    {% csrf_token %}<!--【1】本页面要有post提交,所以加上-->
    新密码:<input type="password" name="pwd">
    <input type="submit" value="确认修改">
</form>
</body>
</html>

あなたは手書きを使用することはできませんので、3)テンプレート/ APP2 / login.htmlと、Ajaxのページです

【参考】します。https:?//code.ziqiangxuetang.com/django/django-csrf.html bd_source_light = 4317393

  1. 使用してビューでレンダリング(というよりもrender_to_response)
  2. カナダでのAjax:
$.ajaxPost({
    data: {csrfmiddlewaretoken: '{{ csrf_token }}' },
});
  1. 詳細コード:[4]保護CSRF
<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <!-- 【0】引入jquery -->
    <script src="/static/js/jquery-1.12.4.min.js"></script>
    <title>登录页面</title>
</head>

<script>
    // 写ajax处理函数
    $(function () {
        $('#btnLogin').click(function () {
            //1.获取用户名、密码、是否记住用户名
            username=$('#username').val()
            password=$('#password').val()
            remember=$('#remember').val() //【2】是否记住用户名
            //2.发起ajax--post(username,password)请求验证,地址:/login_check
            $.ajax({
                'url':'/login_check',//验证地址
                'type':'post',//请求类型
                'data':{//【3】发送数据,加上remember
                    'username':username,
                    'password':password,
                    'remember':remember,
                    csrfmiddlewaretoken: '{{ csrf_token }}',//【4】csrf防护
                    },
                'dataType':'json',//希望返回数据类型
            }).success(function(data){
                //成功返回{'res':1},失败{'res':0}
                if(data.res===0){
                    $('#msg').show().html('用户名或密码错误请重试!')//登录失败则显示msg,并在里写入信息
                }else{//成功跳转到books页面
                    location.href='/change_pwd'
                }
            })

        })
    })
</script>
<style>
    /* 信息提示样式 */
#msg{
    display: none;
    color:red;
}
</style>
<body>
    <!-- 原form删除,input的name变id,方便jquery操作 -->
    <!-- 【4】把views页的login()函数传过来的用户名,密码赋值给对应处 -->
    用户名:<input type="text" id="username" value="{{username}}"><br/>
    密码:<input type="password" id="password" value="{{password}}"><br/>
    <!-- 加入一个信息提示框,用于密码等错误提示 -->
    <div id="msg"></div>
    <!-- 【1】记住用户名,设置cookie用,如果勾选则其value=on -->
    <input type="checkbox" id="remember">记住用户名<br/>
    <!-- 按钮type改button,加一个id方便jquery操作 -->
    <input type="button" id="btnLogin" value="登录">

</body>
</html>

そして、クロスサイト修正(7.6):

<p style="background-color:rgb(255, 255, 204)">
禁止访问 (403)
CSRF验证失败. 请求被中断.
您看到此消息是由于该站点在提交表单时需要一个CSRF cookie。此项是出于安全考虑,以确保您的浏览器没有被第三方劫持。
If you have configured your browser to disable cookies, please re-enable them, at least for this site, or for “same-origin” requests.</p>

1.1.2防衛の原則:

1) 渲染模板文件时在页面生成一个名字叫做csrfmiddlewaretoken的隐藏域。
在网站右键查看源码,可看到这个隐藏域:name=csrfmiddlewaretoken 的input

<form method="post" action="/change_pwd_action/">
    <input type="hidden" name="csrfmiddlewaretoken" value="O6lfnrybooqSP9Je0bZyCOr8qGObvK0jgzV7fMUW259X117OkpAm8OjtCsadu9tk">
    新密码:<input type="password" name="pwd">
    <input type="submit" value="确认修改">
</form>

把上例的隐藏域的value传给服务器。

 <input type="hidden" name="csrfmiddlewaretoken" value="O6lfnrybooqSP9Je0bZyCOr8qGObvK0jgzV7fMUW259X117OkpAm8OjtCsadu9tk">

2) 服务器同时交给浏览器保存一个名字为csrftoken的cookie信息。
3) 提交表单时,两个值都会发给服务器,服务器进行比对,如果一样,则csrf验证通过,否则失败。

二、验证码

  • 在用户注册、登录页面,为了防止暴力请求(穷举法破解用户名密码、自动注册大量账号等),可以加入验证码功能,如果验证码错误,则不需要继续处理,可以减轻业务服务器、数据库服务器的压力。
  • 【其它生成验证码参考】:https://blog.csdn.net/ding_312/article/details/82258442

    1)生成验证码函数 app2/views.py

    【1】存入session,用于做进一步验证
    【2】将图片保存在内存中,文件类型为png
    【3】将内存中的图片数据返回给客户端,MIME类型为图片png
from PIL import Image, ImageDraw, ImageFont
import io

# /verify_code
def verify_code(request):
    # 引入随机函数模块
    import random
    # 定义变量,用于画面的背景色、宽、高 RGB
    bgcolor = (random.randrange(20, 100), random.randrange(20, 100), 255)
    width = 100
    height = 25
    # 创建画面对象
    im = Image.new('RGB', (width, height), bgcolor)
    # 创建画笔对象
    draw = ImageDraw.Draw(im)
    # 调用画笔的point()函数绘制噪点
    for i in range(0, 100):
        xy = (random.randrange(0, width), random.randrange(0, height))
        fill = (random.randrange(0, 255), 255, random.randrange(0, 255))
        draw.point(xy, fill=fill)

    # 定义验证码的备选值
    str1 = 'ABCD123EFGHIJK456LMNOPQRS789TUVWXYZ0' #qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789
    # 随机选取4个值作为验证码
    rand_str = ''
    for i in range(0, 4):
        rand_str += str1[random.randrange(0, len(str1))]

    # 构造字体对象,ubuntu的字体路径为“/usr/share/fonts/truetype/freefont”
    font = ImageFont.truetype('AdobeFanHeitiStd-Bold.otf', 23)
    # 构造字体颜色
    fontcolor = (255, random.randrange(0, 255), random.randrange(0, 255))
    # 绘制4个字
    draw.text((5, 2), rand_str[0], font=font, fill=fontcolor)
    draw.text((25, 2), rand_str[1], font=font, fill=fontcolor)
    draw.text((50, 2), rand_str[2], font=font, fill=fontcolor)
    draw.text((75, 2), rand_str[3], font=font, fill=fontcolor)
    # 释放画笔
    del draw
    # 【1】存入session,用于做进一步验证
    request.session['verifycode'] = rand_str
    # 内存文件操作
    buf = io.BytesIO()
    # 【2】将图片保存在内存中,文件类型为png
    im.save(buf, 'png')
    # 【3】将内存中的图片数据返回给客户端,MIME类型为图片png
    return HttpResponse(buf.getvalue(), 'image/png')

2)app2/urls.py

path('verify_code',views.verify_code),#生成验证码

3)效果:http://127.0.0.1:8000/verify_code

ここに画像を挿入説明

4)在templates/app2/login.html加验证码(这次用表单提交)

【1】添加验证码,直接把验证码地址写在src内

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登录页面</title>
</head>
<body>
<form method="post" action="/login_check">
    {% csrf_token %}
    用户名:<input type="text" name="username" value="{{ username }}"><br/>
    密码:<input type="password" name="password"><br/>
    <input type="checkbox" name="remember">记住用户名<br/>
    <!--【1】添加验证码,直接把地址写在src内-->
    <img src="/verify_code"><br/>
    <input type="text" name="vcode">输入验证码<br/>
    <input type="submit" value="登录">
</form>
</body>
</html>

5)app2/views.py验证函数修改

【1】获取用户输入验证码
【2】获取session中保存的验证码(在第1步)
【3】进行验证码校验,如果验证码输入不对直接返回登录页面,下面的密码验证就不再进行操作了

def login(request):
    '''登录页'''
    # 判断用户是否登录,用户已登录, 直接跳转到图书列表
    if request.session.has_key('islogin'):
        return redirect('/change_pwd/')
    else:
        #如果用户名密码已经在cookie中,则取到它,并做为参数返回给渲染页面
        if 'username' in request.COOKIES:
            #获取cookie中的用户名、密码
            username=request.COOKIES['username']
            #password=request.COOKIES['password']

        else:
            username=''
            #password=''
    return render(request,'app2/login.html',{'username':username}) #,'password':password


def login_check(request):
    '''登录校验'''
    #1.获取用户名密码
    username=request.POST.get('username')
    password=request.POST.get('password')
    remember=request.POST.get('remember') #接收remeber
    
    vcode1 = request.POST.get('vcode') # 【1】获取用户输入验证码
    vcode2 = request.session.get('verifycode') # 【2】获取session中保存的验证码
    # 【3】进行验证码校验,如果验证码输入不对直接返回登录页面,下面的密码验证就不再进行操作了
    if vcode1 != vcode2:
        # 验证码错误
        return redirect('/login')

    #2.进行校验,并返回json数据
    if username=='jim' and password=='123':
        #return redirect('/books')
        response = JsonResponse({'res':1,'msg':'login success!'}) #密码正确,登录成功,返回1

        #如果remember==on,则把用户名,密码设置cookie到cookie
        if remember=='on':
            response.set_cookie('username',username,max_age=7*24*3600)
            #response.set_cookie('password',password,max_age=7*24*3600)
            # 记住用户登录状态把用户名设置到session
            request.session['username'] = username
            # 返回应答
            # 如果用户勾选了remember的条件下,设置session,记住用户登录状态
            request.session['islogin'] = True # 只有session中有islogin,就认为用户已登录
        return response #不要忘记返回response
    else:
        #return redirect('/login')
        return JsonResponse({'res':0,'msg':'login faild'}) #密码错误返回0

6)效果:http://127.0.0.1:8000/login/

ここに画像を挿入説明

  1. 用户名、密码、验证码、都正确返回:1 --登录成功
  2. 有一个错误返回 :0-- 登录失败

三、反向解析

  1. 当某一个url配置的地址发生变化时,页面上使用反向解析生成地址的位置不需要发生变化。
  2. 根据url 正则表达式的配置动态的生成url。
  3. 在项目urls中包含具体应用的urls文件时指定namespace;

1)project2/urls.py配置namespace【重点1】

1-1)Django2.0之后写法

【参考】https://blog.csdn.net/weixin_43883625/article/details/100545439
【1】配置namespace,注意写法:re_path(r'^',include(('app2.urls','booktest'),namespace="booktest"))

from django.contrib import admin
from django.urls import path,include,re_path

urlpatterns = [
    path('admin/', admin.site.urls),
    # 【1】配置namespace,注意写法:include(('app2.urls','booktest'),namespace="booktest")
    re_path(r'^',include(('app2.urls','booktest'),namespace="booktest")),
]

1-2)Django2.0之前写法:project2/urls.py配置namespace

【1】2.0之前写法:url(r'^', include('app2.urls', namespace='booktest')),

"""
from django.conf.urls import include, url
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', include(admin.site.urls)),
    #【1】2.0之前写法:include('app2.urls', namespace='booktest')
    url(r'^', include('app2.urls', namespace='booktest')),
]

2)app2/urls.py配置 【重点2】

【1】 配置name反向解析配置path('index2/', views.index, name='index')

from django.contrib import admin
from django.urls import path,re_path
from . import views

urlpatterns = [
    # 【1】 配置name反向解析配置path('index2/', views.index, name='index')
    path('index/', views.index, name='index'),
    path('url_reverse/', views.url_reverse),
]

3)app2/views.py写url_reverse函数

# /url_reverse
def url_reverse (request):
    return render(request,'app2/url_reverse.html')

4)模板引用templates/app2/url_reverse.html【重点3】

【1】反向解析模板写法 <a href="{% url 'booktest:index' %}">反向解析</a>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>反向解析</title>
</head>
<body>

<a href="/index">写死地址</a>
<br/>

<!--【1】反向解析模板写法-->
<a href="{% url 'booktest:index' %}">反向解析</a>

</body>
</html>

5)效果:http://127.0.0.1:8000/url_reverse/

写死地址 http://127.0.0.1:8000/index
反向解析 http://127.0.0.1:8000/index

  1. 当2步的path('index/', views.index, name='index')path('index2/', views.index, name='index')时。
  2. 写死地址的连接不会变,反向解析会自动变为:http://127.0.0.1:8000/index2

3.2 反向解析+动态传参

1)app2/views.py

from django.shortcuts import render,redirect
from django.http import HttpResponse,JsonResponse

# show_args
def show_args(request, a, b):
    return HttpResponse(a+':'+b)

# show_kwargs
def show_kwargs(request, c, d):
    return HttpResponse(c+':'+d)

2)【重点1:反向解析+传参配置url】app2/urls.py

【1】反向解析+分组传参数
【2】反向解析+字典传参数(以下两种写法都可)

from django.contrib import admin
from django.urls import path,re_path
from . import views

urlpatterns = [
    re_path(r'^show_args/(\d+)/(\d+)', views.show_args,name='show_args'),#【1】反向解析+分组传参数

    #【2】反向解析+字典传参数(以下两种写法都可)
    #path(r'show_kwargs/<str:c>/<str:d>',views.show_kwargs,name='show_kwargs'),
    path(r'show_kwargs/<c>/<d>',views.show_kwargs,name='show_kwargs'),
  ]

3)[キー2:リバース分析パラメータの受け渡し+ +テンプレート文言]テンプレート/ APP2 / url_reverse.html

[1] +分析用逆パケット転送パラメータ:href="{% url 'booktest:show_args' 1 2 %}"
[2] +辞書逆解像度伝送パラメータ:href="{% url 'booktest:show_kwargs' c=3 d=4 %}"

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>反向解析</title>
</head>
<body>

<a href="/index">写死地址</a>
<br/>
<a href="{% url 'booktest:index' %}">反向解析</a>
<hr/>

<br/>
<a href="/show_args/1/2">写死+分组传参:/show_args/1/2</a><br/>

<br/>
<a href="{% url 'booktest:show_args' 1 2 %}">【1】反向解析+分组传参:/show_args/1/2</a><br/>
{% url 'booktest:show_args' 1 2 %}
<hr/>

<br/>
<a href="/show_kwargs/3/4">写死+字典传参:/show_kwargs/3/4</a><br/>
<br/>

<a href="{% url 'booktest:show_kwargs' c=3 d=4 %}">【2】反向解析+字典传参:/show_kwargs/3/4</a><br/>
{% url 'booktest:show_kwargs' c=3 d=4 %}
</body>
</html>

4)の効果:のhttp://127.0.0.1:8000 / url_reverse /を

[1] ハード+パケット転送パラメータ:/ show_args / 1/2
[2]は、ルックアップ逆+パケット転送パラメータ:/ show_args / 1/2
[3] ハード辞書パラメータパッシング+:/ show_kwargs / 3/4
[ 4] 逆分解能質量+辞書参照:/ show_kwargs / 3/4

  • 2)工程が〕となる[[show_args show_args2]、[2] [4]を正しく更新することができるリンク[1] [2]なし
urlpatterns = [
    re_path(r'^show_args2/(\d+)/(\d+)', views.show_args,name='show_args'),#【1】反向解析+分组传参数

    #【2】反向解析+字典传参数(以下两种写法都可)
    #path(r'show_kwargs/<str:c>/<str:d>',views.show_kwargs,name='show_kwargs'),
    path(r'show_kwargs2/<c>/<d>',views.show_kwargs,name='show_kwargs'),
  ]

3.3ビューが逆解像度コールで機能+パラメータを渡します

1)APP2 / views.pyフォーカス[1]

  1. redirect('/index')
  2. reverse('booktest:index')
  3. reverse('booktest:show_args', args=(1,2))
  4. reverse('booktest:show_kwargs', kwargs={'c':3, 'd':4})
  5. 返すことを忘れないでください
# from django.core.urlresolvers import reverse #【0-1】2.0之前导入reverse
from django.urls import reverse #【0-2】2.0之后导入reverse

# /test_redirect
def test_redirect(request):
    # 【0写死】重定向到/index
    # return redirect('/index')
    
    # 【1反向解析】
    # url = reverse('booktest:index')

    # 【2反向解析-分组传参】重定向到/show_args/1/2
    url = reverse('booktest:show_args', args=(1,2))

    # 【3反向解析-字典(关键字)传参】重定向到/show_kwargs/3/4
    #url = reverse('booktest:show_kwargs', kwargs={'c':3, 'd':4})
    return redirect(url)

2)APP2 / urls.py

path('test_redirect/',views.test_redirect),

3)その他の構成は、3.2を参照(キー2)

効果:1)のステップ[0-3]複数の選択肢1件のコメントを表示リフティング効果

ログインします。http://127.0.0.1:対応するURLへ8000 / test_redirect動的逆引き参照。3.2を切り替える方法はありません

おすすめ

転載: www.cnblogs.com/chenxi188/p/12186537.html