1. 程式人生 > 實用技巧 >Django元件:django-simple-captcha 使用 以及新增動態ajax重新整理驗證

Django元件:django-simple-captcha 使用 以及新增動態ajax重新整理驗證

作者:WangC.W

原文:cnblogs.com/wangchaowei/p/6748447.html

參考部落格:http://blog.csdn.net/tanzuozhev/article/details/50458688?locationNum=2&fps=1

參考部落格:http://blog.csdn.net/shanliangliuxing/article/details/9214181

django-simple-captcha是django的驗證碼包,非常簡單實用,這次記錄的是如何點選驗證碼後重新整理驗證碼,因為這個功能官方文件並沒有詳細給出。

django-simple-captcha官方文件:

http://django-simple-captcha.readthedocs.io/en/latest/

django-simple-captcha的github網址:https://github.com/mbi/django-simple-captcha

開始

1.安裝 pip install django-simple-captcha, pip install Pillow

2.將captcha 加入 settings.py 的 INSTALLED_APPS

3.執行 python manager.py migrations 和 python manage.py migrate,以前的版本需要用到 python manage.py syncdb

4.url路由加入urls.py的urlpatterns

urlpatterns = [
url(r'^captcha/', include('captcha.urls')),  # 這是生成驗證碼的圖片
url('^some_view/', finder.views.some_view),  # finder是我的app名字,需要在檔案頭部加入 import finder.views
]

5.在forms.py中加入

from django import forms
from captcha.fields import CaptchaFieldclass
class CaptchaTestForm(forms.Form):
    title = forms.CharField(max_length=100, label='title')
    price = forms.FloatField(max_value=100, label='price')  # 這裡是我們需要的欄位,以title和price為例
    captcha = CaptchaField()  # 為生成的驗證碼圖片,以及輸入框

6.在views.py中加入以下程式碼

def some_view(request):
    if request.POST:
        form = CaptchaTestForm(request.POST)
        # Validate the form: the captcha field will automatically
        # check the input
        if form.is_valid():
            human = True
            return HttpResponse(form.cleaned_data)  # 這裡沒有建立模型,如果成功則直接列印
        else:
            return HttpResponse('validate error')
    else:
        form = CaptchaTestForm()
    return render_to_response('template.html',locals())  # Python 的內建函式 locals() 。它返回的字典對所有區域性變數的名稱與值進行對映

7.template.html 的內容

<!DOCTYPE html>
<html lang="en">
 <head> 
  <meta charset="UTF-8" /> 
  <title>Document</title>
 </head>
 <body>
  <form action="." method="POST">
    {% csrf_token %} {{ form }}
   <input type="submit" value="submit" />
  </form>
 </body>
</html>

8.到此開啟 http://localhost:8000/some_view/ 就有有一個含有驗證碼的title,price的表單

這裡我們簡單說一下驗證碼生成的原理,django-simple-captcha並沒有使用session對驗證碼進行儲存,而是使用了資料庫,首先生成一個表 captcha_captchastore ,包含以下欄位

challenge = models.CharField(blank=False, max_length=32) # 驗證碼大寫或者數學計算比如 1+1
response = models.CharField(blank=False, max_length=32)  # 需要輸入的驗證碼 驗證碼小寫或數學計算的結果 比如 2
hashkey = models.CharField(blank=False, max_length=40, unique=True) # hash值
expiration = models.DateTimeField(blank=False) # 到期時間

9.開啟http://localhost:8000/some_view/ 會發現有一個隱藏欄位

這個隱藏欄位就是hashkey的值,django將hashkey傳給頁面以hidden的形式存在,提交表單時 hashkey與 輸入的驗證碼 一起post到伺服器,此時伺服器驗證 captcha_captchastore表中 hashkey 對應的 response 是否與 輸入的驗證碼一致,如果一致則正確,不一致返回錯誤。


10.django-simple-captcha ajax動態驗證

瞭解了驗證碼生成的原理,我們能就可以用ajax進行動態驗證

將以下程式碼寫入 views.py:

from django.http import JsonResponse
from captcha.models import CaptchaStore

def ajax_val(request):
    if  request.is_ajax():
        cs = CaptchaStore.objects.filter(response=request.GET['response'], hashkey=request.GET['hashkey'])
        if cs:
            json_data={'status':1}
        else:
            json_data = {'status':0}
        return JsonResponse(json_data)
    else:
        # raise Http404
        json_data = {'status':0}
        return JsonResponse(json_data)

11.寫入 urls.py, 為上面的view設定路由

urlpatterns = [
    url(r'^captcha/', include('captcha.urls')) # 這是生成驗證碼的圖片
    url('^some_view/', finder.views.some_view), # finder是我的app名字,需要在檔案頭部加入 import finder.views
    url('^ajax_val/', finder.views.ajax_val, name='ajax_val'), # 新加入
]

12.tempalte.html 寫入ajax

<!DOCTYPE html>
<html lang="en">
 <head> 
  <meta charset="UTF-8" /> 
  <title>Document</title>
 </head>
 <body>
  <form action="." method="POST">
    {% csrf_token %} {{ form }}
   <input type="submit" value="submit" />
  </form> 
  <script>
    $(function(){
    $('#id_captcha_1').blur(function(){
  // #id_captcha_1為輸入框的id,當該輸入框失去焦點是觸發函式
        json_data={
            'response':$('#id_captcha_1').val(), // 獲取輸入框和隱藏欄位id_captcha_0的數值
            'hashkey':$('#id_captcha_0').val()
        }
        $.getJSON('/ajax_val', json_data, function(data){
 //ajax傳送
            $('#captcha_status').remove()
            if(data['status']){ //status返回1為驗證碼正確, status返回0為驗證碼錯誤, 在輸入框的後面寫入提示資訊
                $('#id_captcha_1').after('<span id="captcha_status" >*驗證碼正確</span>')
            }else{
                 $('#id_captcha_1').after('<span id="captcha_status" >*驗證碼錯誤</span>')
            }
        });
    });
    })
    </script> 
  <script src="./jquery.js"></script> 記得匯入jquery.js
 </body>
</html>

至此我們完成了django-simple-captcha 的ajax動態驗證


13.django-simple-captcha ajax重新整理

如果當前驗證碼看不清,我們可以重新整理一下,這個我們用ajax來做。 jango-simple-captcha本身提供了一個重新整理頁面,/refresh 在captcha/urls.py中:

url(r’refresh/$’, views.captcha_refresh, name=’captcha-refresh’)

這裡在我們自己的urls.py中可以不做處理,直接使用 /captcha/refresh/

14.views.captcha_refresh 原始碼

# 只是原始碼介紹不用寫入自己的程式碼中
def captcha_refresh(request):
    """  Return json with new captcha for ajax refresh request """
    if not request.is_ajax():
 # 只接受ajax提交
        raise Http404
    new_key = CaptchaStore.generate_key()
    to_json_response = {
        'key': new_key,
        'image_url': captcha_image_url(new_key),
    }
    return HttpResponse(json.dumps(to_json_response), content_type='application/json')

15.通過閱讀原始碼我們發現, views.captcha_refresh 只接受ajax提交,最後返回 key 和 image_url 的json資料,這裡的key就是 hashkey, 需要我們寫入id為id_captcha_1的隱藏欄位, image_url為驗證碼圖片的新url,這裡我們加入ajax重新整理,點選驗證碼圖片即可實現重新整理,最新的tempalte.html 程式碼為

<!DOCTYPE html>
<html lang="en">
 <head> 
  <meta charset="UTF-8" /> 
  <title>Document</title>
 </head>
 <body>
  <form action="." method="POST">
    {% csrf_token %} {{ form }}
   <input type="submit" value="submit" />
  </form> 
  <script>
    $(function(){
    $('.captcha').css({
        'cursor': 'pointer'
    })
    # ajax 重新整理
    $('.captcha').click(function(){
        console.log('click');
         $.getJSON("/captcha/refresh/",
                  function(result){
             $('.captcha').attr('src', result['image_url']);
             $('#id_captcha_0').val(result['key'])
          });});
    # ajax動態驗證
    $('#id_captcha_1').blur(function(){
  // #id_captcha_1為輸入框的id,當該輸入框失去焦點是觸發函式
        json_data={
            'response':$('#id_captcha_1').val(),  // 獲取輸入框和隱藏欄位id_captcha_0的數值
            'hashkey':$('#id_captcha_0').val()
        }
        $.getJSON('/ajax_val', json_data, function(data){ //ajax傳送            $('#captcha_status').remove()
            if(data['status']){ //status返回1為驗證碼正確, status返回0為驗證碼錯誤, 在輸入框的後面寫入提示資訊
                $('#id_captcha_1').after('<span id="captcha_status" >*驗證碼正確</span>')
            }else{
                 $('#id_captcha_1').after('<span id="captcha_status" >*驗證碼錯誤</span>')
            }
        });
    });
    })
    </script> 
  <script src="./jquery.js"></script> 記得匯入jquery.js
 </body>
</html>

ok, 現在我們已經完成了對django-simple-captcha 的使用,自己學習的心得,希望能幫到更多的小夥伴。