Python瀛︿範涔嬭矾鈥?018/7/11

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python瀛︿範涔嬭矾鈥?018/7/11相关的知识,希望对你有一定的参考价值。

鏍囩锛?a href='http://www.mamicode.com/so/1/git' title='git'>git   mit   log   attr   rip   doc   鍏虫敞   location   length   

Python瀛︿範涔嬭矾鈥?018/7/10

3.1 鐧诲綍楠岃瘉

login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>鍗氬寮€鍙戠郴缁?lt;/title>
    <link rel="stylesheet" href="/static/blog/css/bootstrap.min.css">
    <link rel="icon" href="/static/blog/image/favicon.ico">
    <style type="text/css">
        body {
            background: url(../static/blog/image/bk.jpeg) no-repeat;
            background-size: 100%;
            overflow: hidden;
        }
        h3 {
            padding: 10px;
            border-bottom: 1px solid #ddd;
        }
    </style>
</head>
<body>
<div class="row">
    <div class="col-md-4 col-md-offset-4" style="margin-top: 100px">
        <form>
            {% csrf_token %}
            <div class="well">
                <h3>鐧诲綍</h3>
                <div class="form-group">
                    <label for="username">鐢ㄦ埛鍚?lt;/label>
                    <input type="text" class="form-control" id="username" placeholder="鐢ㄦ埛鍚? autocomplete="off">
                </div>
                <div class="form-group">
                    <label for="password">瀵嗙爜</label>
                    <input type="password" class="form-control" id="password" placeholder="瀵嗙爜" autocomplete="off">
                </div>
                <div class="row form-group">
                    <div class="col-md-6">
                        <label for="password">楠岃瘉鐮?lt;/label>
                        <input type="text" class="form-control" id="verify_code" placeholder="璇疯緭鍏ラ獙璇佺爜" autocomplete="off">
                    </div>
                    <div class="col-md-6">
                        <label for="picture"></label>
                        <img src="/verify_code" style="height: 40px;width: 183px" id="verify_code_img">
                    </div>
                </div>
                <div class="form-group">
                    <span id="error"></span>
                    <input type="button" class="btn btn-success form-control login-btn" value="鐧诲綍">
                </div>
            </div>
        </form>
    </div>
</div>
</body>
<script type="text/javascript" src="/static/blog/js/jquery-3.3.1.min.js"></script>
<script type="text/javascript">
    $("#verify_code_img").click(function () {
        $(this)[0].src += "?"
    });

    $(".login-btn").click(function () {
        $.ajax({
            url: "/login/",
            type: "POST",
            data: {
                "username": $("#username").val(),
                "password": $("#password").val(),
                "verify_code": $("#verify_code").val(),
            },
            success:function (data) {
                    if(data["user"]){
                        location.href = "/index/"
                    }
                    else {
                        $("#error").html(data["msg"]).css({"color": "red"})
                    }
                }
        })
    })
</script>
</html>

views.py

from django.shortcuts import render, HttpResponse
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from django.contrib import auth
from blog.utils.verify_code import *


@csrf_exempt
def login(request):
    if request.method == "GET":
        return render(request, "login.html")
    elif request.method == 鈥楶OST鈥?
        username = request.POST.get("username")
        password = request.POST.get("password")
        verify_codes = request.POST.get("verify_code")
        verify_code_str = request.session.get("verify_code_str")
        response = {"user": None, "msg": None}

        if verify_codes.upper() == verify_code_str.upper():
            user = auth.authenticate(username=username, password=password)
            if user:
                auth.login(request, user)
                response["user"] = user.username
            else:
                response["msg"] = "鐢ㄦ埛鍚嶆垨鑰呭瘑鐮侀敊璇紒"
        else:
            response["msg"] = "楠岃瘉鐮侀敊璇紒"

        return JsonResponse(response)


def verify_code(request):
    data = get_verify_code(request)
    return HttpResponse(data)


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

verify_code.py

import random
from PIL import Image, ImageDraw, ImageFont, ImageFilter
from io import BytesIO


def random_color():
    color = (random.randint(64, 255), random.randint(64, 255), random.randint(64, 255))
    return color


def random_color2():
    color = (random.randint(32, 127), random.randint(32, 127), random.randint(32, 127))
    return color


def random_char():
    """
    闅忔満鏁?瀛楁瘝
    """
    random_num = str(random.randint(0, 9))
    random_low = chr(random.randint(97, 122))  # a~z
    random_upper = chr(random.randint(65, 90))  # A~Z
    random_chars = random.choice([random_num, random_low, random_upper])
    return random_chars


def get_verify_code(request):
    """
    鍔ㄦ€佺敓鎴愰獙璇佺爜
    """
    image = Image.new("RGB", (183, 40), (255, 255, 255))
    image_font = ImageFont.truetype("static/blog/font/Arial.ttf", 32)
    draw = ImageDraw.Draw(image)

    # 缁欐瘡涓潗鏍囧~鍏呴鑹?濉厖鍣偣
    for x in range(183):
        for y in range(40):
            draw.point((x, y), fill=random_color())

    verify_code_str = ""
    for i in range(5):
        random_chars = random_char()
        verify_code_str += random_chars
        draw.text((20+i*30, 0), random_chars, font=image_font, fill=random_color2())
    image = image.filter(ImageFilter.BLUR)  # 妯$硦澶勭悊
    
    # 鏀惧埌纾佺洏涓紝浣嗘槸閫熷害姣旇緝鎱紝鎺ㄨ崘鏀惧湪鍐呭瓨涓?    # with open("verify_code.png", "wb") as f:
    #     image.save(f)
    #
    # with open("verify_code.png", "rb") as f:
    #     data = f.read()
    
    request.session["verify_code_str"] = verify_code_str
    f = BytesIO()
    image.save(f, "png")
    data = f.getvalue()

    return data

鐧诲綍鐣岄潰鏁堟灉濡備笅鍥炬墍绀猴細

鎶€鏈垎浜浘鐗? src=

鎬荤粨锛?/h4>
  1. 涓€娆¤姹備即闅忕潃澶氭闈欐€佺殑璇锋眰锛屼緥濡俢ss鏂囦欢鐨勮姹?/li>
  2. 鍒╃敤PIL妯″潡鍔ㄦ€佸埗浣滈獙璇佺爜
  3. 楠岃瘉鐮佷娇鐢╯ession瀛樺偍锛坰ession棣栧厛浼氱敓鎴愪竴涓猻essionid锛屾帴鐫€浼氬湪cookie涓瓨鍌╯essionid锛屾渶鍚庢兂session琛ㄤ腑鎻掑叆鏁版嵁锛屽寘鎷瑂essionid浠ュ強session鍐呭锛屼竴涓祻瑙堝櫒瀵瑰簲涓€鏉ession鏁版嵁锛?/li>
  4. 楠岃瘉鐮佺殑鍒锋柊锛屾瘡娆$偣鍑婚獙璇佸姛鑳藉浘鐗囨椂锛屽湪鍏秙rc鐨勬湯灏惧姞涓??锛岃繖鏍锋瘡娆$偣鍑诲浘鐗囦究浼氬埛鏂伴獙璇佺爜
  5. 閬靛惊鈥滈珮鑰﹀悎浣庡唴鑱氣€濆師鍒欙紝灏嗗姩鎬佺敓鎴愰獙璇佺爜鐨勫姛鑳藉瓨鏀惧湪鍙︿竴涓猵y鏂囦欢涓?/li>

https://github.com/GeeTeam/gt-python-sdk/ 涓嬭浇geetest.py 锛屽皢鍏舵斁鍏ラ」鐩腑

login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>鍗氬寮€鍙戠郴缁?lt;/title>
    <link rel="stylesheet" href="/static/blog/css/bootstrap.min.css">
    <link rel="stylesheet" href="/static/blog/css/blog.css">
    <link rel="icon" href="/static/blog/image/favicon.ico">
    <style type="text/css">
        body {
            background: url(../static/blog/image/bk.jpeg) no-repeat;
            background-size: 100%;
            overflow: hidden;
        }
    </style>
</head>
<body>
<div class="row">
    <div class="col-md-4 col-md-offset-4" style="margin-top: 100px">
        <form>
            {% csrf_token %}
            <div class="well">
                <div class="login-head">
                    {% block head %}
                        <h3 style="display: inline-block">鐧诲綍</h3>
                        <a id="register">绔嬪嵆娉ㄥ唽</a>
                    {% endblock head %}
                </div>
                {% block content %}}
                    <div class="form-group">
                        <label for="username">鐢ㄦ埛鍚?lt;/label>
                        <input type="text" class="form-control" id="username" placeholder="鐢ㄦ埛鍚? autocomplete="off">
                    </div>
                    <div class="form-group">
                        <label for="password">瀵嗙爜</label>
                        <input type="password" class="form-control" id="password" placeholder="瀵嗙爜" autocomplete="off">
                    </div>
                {% endblock content %}
                <div class="form-group">
                    <span id="error"></span>
                    {% block submit %}
                        <input type="button" class="btn btn-success form-control login-btn" value="鐧诲綍">
                    {% endblock submit %}
                </div>
                <div id="popup-captcha"></div>
            </div>
        </form>
    </div>
</div>
</body>
<script type="text/javascript" src="/static/blog/js/jquery-3.3.1.min.js"></script>
<script src="https://static.geetest.com/static/tools/gt.js"></script>
<script src="/static/blog/js/blog.js"></script>
</html>

blog.css

a:hover {
    cursor: pointer;
    text-decoration: none;
}

.login-head {
    margin-bottom: 10px;
    border-bottom: 1px solid #ddd;
}

.login-head a {
    margin-left: 287px;
    color: #5cb85c;
}

blog.js

var handlerPopup = function (captchaObj) {
    // 鎴愬姛鐨勫洖璋?    captchaObj.onSuccess(function () {
        var validate = captchaObj.getValidate();
        $.ajax({
            url: "/login/", // 杩涜浜屾楠岃瘉
            type: "post",
            dataType: "json",
            data: {
                username: $(鈥?username鈥?.val(),
                password: $(鈥?password鈥?.val(),
                geetest_challenge: validate.geetest_challenge,
                geetest_validate: validate.geetest_validate,
                geetest_seccode: validate.geetest_seccode
            },
            success: function (data) {
                if(data["user"]){
                    location.href = "/index/"
                }
                else {
                    $("#error").html(data["msg"]).css({"color": "red"})  //鎻愮ず閿欒淇℃伅
                }
            }
        });
    });
    $(".login-btn").click(function () {
        captchaObj.show();
    });
    // 灏嗛獙璇佺爜鍔犲埌id涓篶aptcha鐨勫厓绱犻噷
    captchaObj.appendTo("#popup-captcha");
    // 鏇村鎺ュ彛鍙傝€冿細http://www.geetest.com/install/sections/idx-client-sdk.html
};
// 楠岃瘉寮€濮嬮渶瑕佸悜缃戠珯涓诲悗鍙拌幏鍙杋d锛宑hallenge锛宻uccess锛堟槸鍚﹀惎鐢╢ailback锛?$.ajax({
    url: "/pc-geetest/register?t=" + (new Date()).getTime(), // 鍔犻殢鏈烘暟闃叉缂撳瓨
    type: "get",
    dataType: "json",
    success: function (data) {
        // 浣跨敤initGeetest鎺ュ彛
        // 鍙傛暟1锛氶厤缃弬鏁?        // 鍙傛暟2锛氬洖璋冿紝鍥炶皟鐨勭涓€涓弬鏁伴獙璇佺爜瀵硅薄锛屼箣鍚庡彲浠ヤ娇鐢ㄥ畠鍋歛ppendTo涔嬬被鐨勪簨浠?        initGeetest({
            gt: data.gt,
            challenge: data.challenge,
            product: "popup", // 浜у搧褰㈠紡锛屽寘鎷細float锛宔mbed锛宲opup銆傛敞鎰忓彧瀵筆C鐗堥獙璇佺爜鏈夋晥
            offline: !data.success // 琛ㄧず鐢ㄦ埛鍚庡彴妫€娴嬫瀬楠屾湇鍔″櫒鏄惁瀹曟満锛屼竴鑸笉闇€瑕佸叧娉?            // 鏇村閰嶇疆鍙傛暟璇峰弬瑙侊細http://www.geetest.com/install/sections/idx-client-sdk.html#config
        }, handlerPopup);
    }
});

views.py

from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from blog.utils.geetest import GeetestLib
from django.contrib import auth

@csrf_exempt
def login(request):
    if request.method == "GET":
        return render(request, "login.html")
    elif request.method == 鈥楶OST鈥?
        # 婊戝姩楠岃瘉鐮侊紝鍒╃敤geetest鎻掍欢
        gt = GeetestLib(pc_geetest_id, pc_geetest_key)
        status = request.session[gt.GT_STATUS_SESSION_KEY]
        username = request.POST.get("username")
        password = request.POST.get("password")
        response = {"user": None, "msg": None}
        if status:
            user = auth.authenticate(username=username, password=password)
            if user:
                auth.login(request, user)
                response["user"] = user.username
            else:
                response["msg"] = "鐢ㄦ埛鍚嶆垨鑰呭瘑鐮侀敊璇紒"
        return JsonResponse(response)

灞曠ず鏁堟灉锛?br> 鎶€鏈垎浜浘鐗? src=

3.2 娉ㄥ唽鐢ㄦ埛

棣栧厛鍦ㄩ」鐩腑鍒涘缓media鏂囦欢澶癸紝鍦╩edia鐩綍涓嬪垱寤篴vatars鏂囦欢澶癸紝杩欎釜鏂囦欢涓昏瀛樻斁鐢ㄦ埛涓婁紶鐨勬枃浠?/p>

Django鏈変袱绉嶉潤鎬佹枃浠讹紝鍒嗗埆鏄痵tatic浠ュ強media锛宻tatic涓昏瀛樻斁js,css,img绛夋湇鍔″櫒鑷繁鐨勬枃浠讹紝鑰宮edia涓昏瀛樻斁鐢ㄦ埛涓婁紶鐨勬枃浠躲€?/p>

鎴戜滑闇€瑕侀厤缃畇ettings涓殑media淇℃伅MEDIA_ROOT = os.path.join(BASE_DIR, "media")锛岄厤缃ソ浠ュ悗姣忔鐢ㄦ埛涓婁紶鐨勬枃浠禗jango浼氬瓨鏀惧埌/media/avatars鐩綍涓嬶紝濡傛灉鐢ㄦ埛娌℃湁鍒涘缓avatars鐩綍锛孌jango浼氳嚜鍔ㄥ垱寤鸿鐩綍

register.html

{% extends "login.html" %}
{% block head %}
    <h3 style="text-align: center">娉ㄥ唽</h3>
{% endblock %}

{% block content %}
    {% for foo in form %}
        <div class="form-group">
            <label for="{{ foo.auto_id }}">{{ foo.label }}</label>
            {{ foo }}
            <span class="error pull-right"></span>
        </div>
    {% endfor %}
    <div class="form-group">
        <label for="avatar">
            澶村儚
            <img src="/static/blog/avatars/default.gif" id="avatar_img">
        </label>
        <input type="file" id="avatar" style="display: none">
    </div>
{% endblock content %}

{% block submit %}
    <input type="button" class="btn btn-success form-control" value="娉ㄥ唽">
{% endblock submit %}

blog.css

#avatar_img {
    width: 60px;
    height: 60px;
    margin-left: 20px;
}
.error{
    color: red;
}

blog.js

// input鏍囩鍐呭鏀瑰彉浜嬩欢锛屽嵆澶村儚涓婁紶
$("#avatar").change(function () {
   var file = $(this)[0].files[0];  // 鑾峰彇鍥剧墖璺緞
   var reader = new FileReader();  // 鏂囨湰闃呰鍣?   reader.readAsDataURL(file);  // 璇诲彇鏂囦欢鐨勮矾寰?   reader.onload = function () {
       $("#avatar_img").attr("src", reader.result)  // 灏嗗浘鐗囩殑璺緞鍐欏叆img鏍囩鐨剆rc涓?   }
});
// 娉ㄥ唽鐢ㄦ埛
$(".reg-btn").click(function () {
    var formdata = new FormData();
    var request_list = $("#form").serializeArray();  // 鍖呭惈form琛ㄥ崟涓墍鏈夋爣绛剧殑name鍜寁alue
    $.each(request_list, function (index, data) {
        formdata.append(data.name, data.value)
        /*
        鐩稿綋浜庯細
            formdata.append("username",$("#id_username").val());
            formdata.append("password",$("#id_password").val());
            formdata.append("re_password",$("#id_re_password").val());
            formdata.append("email",$("#id_email").val());
        */
    });
    formdata.append("avatar", $("#avatar")[0].files[0]);
    $.ajax({
        url: "/register/",
        type: "POST",
        contentType: false,  // 蹇呭姞鍙傛暟
        processData: false,  // 蹇呭姞鍙傛暟
        data: formdata,
        success: function (data) {
            $("span.error").html("");  // 绉婚櫎涓婁竴娆$殑閿欒淇℃伅
            $(".has-error").removeClass("has-error");  // 绉婚櫎涓婁竴娆¢敊璇俊鎭鏍峰紡
            if (data.user) {
                location.href = "/login/"  //娉ㄥ唽鎴愬姛鍒欒繑鍥炵櫥褰曠晫闈?            }
            else {
                var error_list = data.msg;
                $.each(error_list, function (field, error) {
                    if (field == "__all__"){
                        $("#id_re_password").next().html(error[0]).parent().addClass("has-error")  // 瀵瑰叏灞€閽╁瓙鐨勫崟鐙鐞?                    }
                    $("#id_" + field).next().html(error[0]);  // 鎵惧瀵瑰簲id鐨刬nput鏍囩鍚庨潰鐨剆pan鏍囩锛屽皢閿欒淇℃伅鍐欏叆
                    $("#id_" + field).parent().addClass("has-error");  // 缁欏惈鏈夐敊璇俊鎭殑input鏍囩娣诲姞css鏍峰紡
                })
            }
        }
    })
});

my_forms.py

from django import forms
from .models import *
from django.core.exceptions import ValidationError

wid_1 = forms.widgets.TextInput(attrs={"class": "form-control", "autocomplete": "off"})
wid_2 = forms.widgets.PasswordInput(attrs={"class": "form-control"})


class UserForm(forms.Form):
    username = forms.CharField(max_length=32, label="鐢ㄦ埛鍚?, widget=wid_1,
                               error_messages={"required": "璇ュ瓧娈典笉鑳戒负绌猴紒"})
    password = forms.CharField(min_length=8, label="瀵嗙爜", widget=wid_2,
                               error_messages={"min_length": "瀵嗙爜闀垮害鑷冲皯8浣嶏紒",
                                               "required": "璇ュ瓧娈典笉鑳戒负绌猴紒"})
    re_password = forms.CharField(min_length=8, label="纭瀵嗙爜", widget=wid_2,
                                  error_messages={"min_length": "瀵嗙爜闀垮害鑷冲皯8浣嶏紒",
                                                  "required": "璇ュ瓧娈典笉鑳戒负绌猴紒"})
    email = forms.EmailField(label="閭", widget=wid_1,
                             error_messages={"invalid": "閭鏍煎紡閿欒锛?})

    def clean_username(self):
        username = self.cleaned_data.get("username")
        user = User.objects.filter(username=username)
        if not user:
            return username
        else:
            raise ValidationError("璇ョ敤鎴峰凡缁忚娉ㄥ唽锛?)

    def clean(self):
        password = self.cleaned_data.get("password")
        re_password = self.cleaned_data.get("re_password")

        if password == re_password:
            return self.cleaned_data
        else:
            raise ValidationError("涓ゆ瀵嗙爜涓嶄竴鑷达紒")

views.py

from blog.my_forms import *

def register(request):
    user = UserForm()
    if request.method == "GET":
        return render(request, "register.html", locals())
    elif request.method == "POST":
        response = {"user": None, "msg": None}
        user = UserForm(request.POST)
        if user.is_valid():
            username = user.cleaned_data.get("username")
            response["user"] = username
            password = user.cleaned_data.get("password")
            email = user.cleaned_data.get("email")
            avatar_obj = request.FILES.get("avatar")
            if avatar_obj:  # 濡傛灉鐢ㄦ埛涓婁紶浜嗗ご鍍忥紝鍒欏垱寤虹敤鎴锋椂灏嗗叾浼犲叆锛屾病鏈夊垯浼犻€掑叾浠栧~鍐欑殑淇℃伅
                user_obj = User.objects.create_user(username, email, password, avatar=avatar_obj)
            else:
                user_obj = User.objects.create_user(username, email, password)
        else:
            response["msg"] = user.errors  # 鍖呭惈浜嗘墍鏈夌殑閿欒淇℃伅

        return JsonResponse(response)

灞曠ず鏁堟灉锛?/p>

鎶€鏈垎浜浘鐗? src=

鎬荤粨锛?/h4>
  1. label鏍囩娣诲姞for灞炴€э紙鍐呭涓烘煇涓爣绛剧殑id锛夛紝鐐瑰嚮label鐩稿綋浜庣偣鍑籪or灞炴€т腑鐨勬爣绛俱€傚埄鐢ㄦ鐗规€э紝灏嗘枃浠朵笂浼爄nput闅愯棌锛屾坊鍔犱竴涓猯abel涓庡叾缁戝畾锛屾帴鐫€鍦╨abel涓坊鍔爄mg锛岃繖鏍风偣鍑诲浘鐗囦究鍙互瀹炵幇鏂囦欢涓婁紶銆?/li>
  2. 鏂囦欢鐨勮矾寰勯€氳繃$(xx)[0].files[0]鏉ヨ幏鍙?/li>
  3. 瀹炵幇涓婁紶澶村儚鐨勯瑙堜富瑕佸垎涓轰笁姝ワ紝绗竴鑾峰彇鍥剧墖鐨勮矾寰勶紝绗簩姝ヨ鍙栧浘鐗囩殑璺緞锛岀涓夋灏嗗浘鐗囪矾寰勫啓鍏mg鏍囩涓?/li>
  4. 鏂囨湰闃呰鍣ㄤ腑鐨剅eadAsDataURL鏄紓姝ョ殑锛屾墍浠ヤ細鍑虹幇杩樻病鏈夎鍙栧浘鐗囪矾寰勫氨鍐欏叆浜嗭紝浠庤€屼骇鐢熶竴涓猽nknow瀵硅薄锛屾墍浠ラ渶瑕佺敤鍒皁nload鏂规硶锛宱nload浼氬湪鎵€鏈夎祫婧愬姞杞藉畬涔嬪悗杩愯銆?/li>
  5. 涓婁紶鏂囦欢鏃堕渶瑕佺敤鍒癋ormData,浣跨敤FormData鏃跺繀椤诲姞ajax涓姞contentType: false,processData: false杩欎袱涓弬鏁?/li>
  6. 鍚慒ormData涓彃鍏ユ暟鎹殑鏃跺€欙紝鍙互閫氳繃$("xxx").serializeArray()锛堝寘鍚簡form琛ㄥ崟涓墍鏈夎緭鍏ユ鐨刵ame浠ュ強value锛夊惊鐜坊鍔狅紝鍑忓皯浠g爜閲?/li>
  7. Media鐨勯厤缃紝灏嗘湇鍔″櫒鐨勬枃浠跺瓨鏀惧湪static涓紝鐢ㄦ埛涓婁紶鐨勬枃浠跺瓨鏀惧湪media/avatars涓?/li>

以上是关于Python瀛︿範涔嬭矾鈥?018/7/11的主要内容,如果未能解决你的问题,请参考以下文章

Python瀛︿範涔嬭緭鍏ュ拰杈撳嚭

python瀛︿範涔嬫姄鍙栫尗鐪肩數褰盩op100姒滃崟

娴嬪紑涔嬭矾涓€鐧鹃浂鍥涳細jquery鎿嶄綔鏍峰紡

鎴戠殑鍏ㄦ爤涔嬭矾-C璇█鍩虹涔婥绋嬪簭杩愯娴佺▼

Kettle瀛︿範涔婼poon浣跨敤

spring瀛︿範涔媋op(FactoryBean浠g悊)