django form POST方法提交表達

之前就着手開始嘗試用django來簡化web開發的流程週期,果不其然,速度還行,當然前期的產品那就相當粗糙了。舉例來說,就連最基本的登錄都是抄別人的,最可怕的是用GET方法提交表單,今天就嘗試解決這個問題,用POST方法來提交登錄數據。

做過web開發的都知道相對而言,POST方法比GET方法更安全,真的是這樣麼?

下面先具體說明如何用GET方法提交表單:

template模板代碼:

<form id="login" class="form-horizontal" role="form" action="/login" method="get" onSubmit="return validate_form(this)">
  <div class="form-group" >
    <div class="login-l"><label for="username" class="col-sm-2 control-label">用戶名</label></div>
    <div class="col-sm-2 login-r" >
      <input type="text" class="form-control" id="username" name="username" placeholder="Username">
    </div>
  </div>
  <div class="form-group">
    <div class="login-l"><label for="inputPassword3" class="col-sm-2 control-label">密碼</label></div>
    <div class="col-sm-2 login-r">
      <input type="password" class="form-control" id="password" name="password" placeholder="Password">
    </div>
  </div>
  <div class="form-group" >
    <div class="col-sm-offset-2 col-sm-10" >
      <div class="checkbox">
        <label>
          <input type="checkbox"> 記住我
        </label>
      </div>
    </div>
  </div>
  <div class="form-group">
    <div class="col-sm-offset-2 col-sm-10" >
      <button type="submit" class="btn btn-default" >登錄</button>
      {% if error %}
          <font color="red">{{ error }}</font>
      {% endif %}
    </div>
  </div>
</form>

 

 views.py邏輯處理代碼:

from django.shortcuts import render_to_response
from django.contrib import auth

def index(request):
    # current_date=datetime.datetime.now()
    if request.user.is_authenticated():
        'if the session remains , auto login'
        return render_to_response('srvMonitor/srvstatus.html')
    else:
        return render_to_response('login.html')

def login(request):
    username = request.GET.get('username')
    password = request.GET.get('password')
    User = auth.authenticate(username=username, password=password)

    if User is not None and User.is_active:
        auth.login(request, User)
        return render_to_response('srvMonitor/srvstatus.html')
    else:
        return render_to_response('login.html', {'error': "用戶名密碼錯誤"})

 

get方法來提交表單在settings.py中基本沒啥很多需要配置的。

下面再說下如何用POST方法來提交表單,如果在上面代碼的基礎上直接把模板中的提交方法從GET改爲POST,必定會報下面的錯誤:

Forbidden (403) CSRF verification failed. Request aborted.Help Reason given for failure: CSRF token missing or incorrect.

In general, this can occur when there is a genuine Cross Site Request Forgery, or when Django's CSRF mechanism has not been used correctly. 
For POST forms, you need to ensure: Your browser is accepting cookies. The view function uses RequestContext for the template, 
instead of Context. In the template, there is a {% csrf_token %} template tag inside each POST form that targets an internal URL. 
If you are not using CsrfViewMiddleware, then you must use csrf_protect on any views that use the csrf_token template tag, 
as well as those that accept the POST data. You're seeing the help section of this page because you have DEBUG = True in your Django settings file.
 Change that to False, and only the initial error message will be displayed. You can customize this page using the CSRF_FAILURE_VIEW setting.

 

從報錯中可以看出需要配置三個地方:

1. settings.py需要設置:APPEND_SLASH = False

2. 提交表單的form中需要添加 {% csrf_token %}

3. 處理提交表達邏輯中需要添加修飾符 @csrf_protect, 跳轉需要添加 context_instance=RequestContext(request) 

也就是下面的幾項:

template模板代碼:

<form id="login" class="form-horizontal" role="form" action="/login" method="post" onSubmit="return validate_form(this)">
  {% csrf_token %}
  <div class="form-group" >
    <div class="login-l"><label for="username" class="col-sm-2 control-label">用戶名</label></div>
    <div class="col-sm-2 login-r" >
      <input type="text" class="form-control" id="username" name="username" placeholder="Username">
    </div>
  </div>
  <div class="form-group">
    <div class="login-l"><label for="inputPassword3" class="col-sm-2 control-label">密碼</label></div>
    <div class="col-sm-2 login-r">
      <input type="password" class="form-control" id="password" name="password" placeholder="Password">
    </div>
  </div>
  <div class="form-group" >
    <div class="col-sm-offset-2 col-sm-10" >
      <div class="checkbox">
        <label>
          <input type="checkbox"> 記住我
        </label>
      </div>
    </div>
  </div>
  <div class="form-group">
    <div class="col-sm-offset-2 col-sm-10" >
      <button type="submit" class="btn btn-default" >登錄</button>
      {% if error %}
          <font color="red">{{ error }}</font>
      {% endif %}
    </div>
  </div>
</form>

views.py邏輯代碼:

from django.contrib import auth
from django.views.decorators.csrf import csrf_protect

def index(request):
    # current_date=datetime.datetime.now()
    if request.user.is_authenticated():
        'if the session remains , auto login'
        return render_to_response('srvMonitor/srvstatus.html')
    else:
        return render_to_response('login.html',
                                  context_instance=RequestContext(request))

@csrf_protect
def login(request):
    username = request.POST.get('username')
    password = request.POST.get('password')
    User = auth.authenticate(username=username, password=password)

    if User is not None and User.is_active:
        auth.login(request, User)
        return render_to_response('srvMonitor/srvstatus.html')
    else:
        return render_to_response('login.html', {'error': "用戶名密碼錯誤"},
                                  context_instance=RequestContext(request))

 

settings.py配置代碼:

MIDDLEWARE_CLASSES = (
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
)
APPEND_SLASH = False

 

這個還是比較簡單的,主要是找網上的那些資料真心不容易,某牆前幾天連honxi都沒法翻過去了,真實坑死了我們這羣苦逼民工。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章