程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

Python introductory self-study advanced web framework - 14. Djangos form verification

編輯:Python

Django Of Form verification

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="logintest.html" method="post">
<p> User name :<input type="text" name="username" placeholder=" Please enter a user name "></p>
<p> User mailbox :<input type="text" name="email" placeholder=" Please enter the user email "></p>
<p> User mailbox :<input type="password" name="pwd" placeholder=" Please enter the user password "></p>
{% csrf_token %}
<input type="submit" value="Form Submit ">
<input id="ajax_submit" type="button" value="Ajax Submit ">
</form>
<script src="/static/jquery-3.6.0.js"></script>
<script>
$(function () {
$("#ajax_submit").click(function () {
$.ajax({
url: "logintest.html",
data: {username:'root',email:'[email protected]',pwd:'123123',csrfmiddlewaretoken: '{
{ csrf_token }}'},
type:'POST',
success:function (arg) {
console.log(arg);
}
})
})
})
</script>
</body>
</html>
def logintest(req):
if req.method == "GET":
return render(req,'logintest.html')
elif req.method == "POST":
u = req.POST.get("username")
e = req.POST.get("email")
p = req.POST.get("pwd")
print(" Process the acquired data :1, check ;2, Database operation ",u,e,p)
return render(req,'logintest.html',{})

There are several problems :
1、 Verify the data submitted by the user , The prompt information shall be accurate , That is, the input of which field does not meet the requirements , In which field will the error message be prompted ;
2、 If more data items are submitted , backstage req.POST.get() There will be a lot of ;
3、 If you want to operate the database , If you use filter() or create(), A large number of parameters such as username=,email=,pwd=... Equal length parameter ;
4、 For front-end , If the data item validation fails , That is, through form Submitted form , At this point, all the front-end data is cleared , And we expect that the correct input field data is still ( Of course ,ajax Submission does not address this issue ,ajax The data still exists after submission );

Verification of user submitted data

length 、 type 、 Format validation , High reusability .

Verification is divided into front end and back end

Back end , Use a template :
- Email format
- user , Name length >4
- password , length >7

Django Provides Form Validate class templates :

# Define templates
from django import forms
class LoginForm(forms.Form):
# Elements in the template
username = forms.CharField(min_length=4)
email = forms.EmailField()

Use validation classes to validate :

def logintest(req):
if req.method == "GET":
return render(req,'logintest.html')
elif req.method == "POST":
obj = LoginForm(req.POST)
# verification
status = obj.is_valid()
value_right = obj.clean()
print('value_right:',value_right)
value_error = obj.errors
print('value_error:',value_error)
print('status:',status)
if obj.is_valid():
value_right = obj.clean()
# create(**value_right) Add records to the database , Parameters are used directly **value_right
else:
value_error = obj.errors.as_json()
print('value_error_asjson:',value_error)
return render(req,'logintest.html',{})

Define a template first , This template should inherit from django Of forms Medium Form class , Then define the elements , Be careful , The variable name here , Such as username、email Not random , Must contact the front desk form Of each submitted data tag in the form name Value consistent , Then there is the... With specific verification functions CharField()、EmailField() etc. . Use this template in the view function
To verify , First instantiate a template object , take req.POST As a parameter , This will automatically get POST To verify the corresponding value in . Generating objects does not validate , You also need to call is_valid() Method , Only then will it be verified , The result is True or False, No measures for verification , Will return True, As long as there is a field validation error , Namely False.clean() The method is to get a dictionary that verifies the correct fields ,errors Is an unordered list string of error fields and error messages , Use as_json() Convert to json character string .

  because email Field input does not conform to emailed Format , Validation error ,value_error, namely errors Show email Error list information for , Convert to json String display format ,is_valid() The result is false.clean() Just a dictionary of the correct fields .

Here's a question , If there are no defined fields in the template , stay clean() Cannot get in , Like here. pwd Field , You also need to use POST.get() obtain .

Through error messages json Format , You can see the types of errors , namely code Value , Here you are invalid—— Format does not match ,min_length—— The minimum length is not enough ,required—— Field requires a value , That is, the field is empty . Corresponding message Is the description of the corresponding error code , It can be explained in Chinese characters . 

# Define templates
from django import forms
class LoginForm(forms.Form):
# Elements in the template
username = forms.CharField(min_length=4,error_messages={"min_length":" User name length cannot be less than 4","required":" The username cannot be empty "})
email = forms.EmailField(error_messages={"invalid":" The format of mailbox name does not meet the requirements ","required":" The mailbox cannot be empty "})

Run print results :

value_right: {}
value_error: <ul class="errorlist"><li>username<ul class="errorlist"><li> The username cannot be empty </li></ul></li><li>email<ul class="errorlist"><li> The mailbox cannot be empty </li></ul></li></ul>
status: False
value_error_asjson: {"username": [{"message": "\u7528\u6237\u540d\u4e0d\u80fd\u4e3a\u7a7a", "code": "required"}], "email": [{"message": "\u90ae\u7bb1\u4e0d\u80fd\u4e3a\u7a7a", "code": "required"}]}

Convert to json when , Chinese characters are converted to Unicode It's encoded .

  about errors attribute , Look through the print results , It seems to be a string , What is it ? adopt type(obj.errors), Print out the type :<class 'django.forms.utils.ErrorDict'>, Is a wrong dictionary , Take a look at the source code of this class :

@html_safe
class ErrorDict(dict):
"""
A collection of errors that knows how to display itself in various formats.
The dictionary keys are the field names, and the values are the errors.
"""
def as_data(self):
return {f: e.as_data() for f, e in self.items()}
def get_json_data(self, escape_html=False):
return {f: e.get_json_data(escape_html) for f, e in self.items()}
def as_json(self, escape_html=False):
return json.dumps(self.get_json_data(escape_html))
def as_ul(self):
if not self:
return ''
return format_html(
'<ul class="errorlist">{}</ul>',
format_html_join('', '<li>{}{}</li>', self.items())
)
def as_text(self):
output = []
for field, errors in self.items():
output.append('* %s' % field)
output.append('\n'.join(' * %s' % e for e in errors))
return '\n'.join(output)
def __str__(self):
return self.as_ul()

Inherited from Dictionary dict, We see that as_json(), The return is json.dumps(), Is converted to json Format string . And its __str__() Is to return as_ul(), see as_ul(), The format is the printed result we see .

because errors It's a <class 'django.forms.utils.ErrorDict'>, Use obj.errors['email'] Visit , namely
print(obj.errors['email']) The result is :<ul class="errorlist"><li> The mailbox cannot be empty </li></ul>, Is this a string ? Print type print(type(obj.errors['email'])), The result is :<class 'django.forms.utils.ErrorList'>, It's a list , You can get... By subscript :print('value_error:',value_error['email'][0]), result :value_error: The mailbox cannot be empty .

in other words , It's generating obj Object time , Relevant error messages are stored in the object , You can pass this object to the front end :

def logintest(req):
if req.method == "GET":
return render(req,'logintest.html')
elif req.method == "POST":
obj = LoginForm(req.POST)
# verification
status = obj.is_valid()
value_right = obj.clean()
print('value_right:',value_right)
value_error = obj.errors
print('value_error:',value_error['email'][0])
print('status:',status)
if obj.is_valid():
value_right = obj.clean()
# create(**value_right) Add records to the database , Parameters are used directly **value_right
else:
value_error = obj.errors.as_json()
print('value_error_asjson:',value_error)
return render(req,'logintest.html',{'oo':obj})
<form action="logintest.html" method="post">
<p> User name :<input type="text" name="username" placeholder=" Please enter a user name "><span>{
{ oo.errors.username.0 }}</span></p>
<p> User mailbox :<input type="text" name="email" placeholder=" Please enter the user email "><span>{
{ oo.errors.email.0 }}</span></p>
<p> User mailbox :<input type="password" name="pwd" placeholder=" Please enter the user password "></p>

The front end only needs to display an error message , So just take the index 0 Value . For the first get request , No delivery oo object , about django Come on , No objects , Back to you null, But for other languages , It's possible to make a mistake .

Now there is another problem ,form After submission , If there is a field error , You want the field to retain the information you entered , To implement this function , We can't write it ourselves input label , need Form To achieve .

obj = LoginForm()
print(obj['username'])
print(obj['email'])

The result is :
<input type="text" name="username" minlength="4" required id="id_username">
<input type="email" name="email" required id="id_email">

For objects that do not pass parameters ,obj['username'] Is to generate a input label .

Pass a parameter :obj=LoginForm({'username':'qwert','email':'[email protected]}), The result is

<input type="text" name="username" value="qwert" minlength="4" required id="id_username">
<input type="email" name="email" value="[email protected]" required id="id_email">

On the front end , You can use this method to automatically generate input label :

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="logintest.html" method="post">
<p> User name :{
{ oo.username }}<span>{
{ oo.errors.username.0 }}</span></p>
<p> User mailbox :{
{ oo.email }}<span>{
{ oo.errors.email.0 }}</span></p>
<p> User mailbox :<input type="password" name="pwd" placeholder=" Please enter the user password "></p>
{% csrf_token %}
<input type="submit" value="Form Submit ">
<input id="ajax_submit" type="button" value="Ajax Submit ">
</form>
<script src="/static/jquery-3.6.0.js"></script>
<script>
$(function () {
$("#ajax_submit").click(function () {
$.ajax({
url: "logintest.html",
data: {username:'root',email:'[email protected]',pwd:'123123',csrfmiddlewaretoken: '{
{ csrf_token }}'},
type:'POST',
success:function (arg) {
console.log(arg);
}
})
})
})
</script>
</body>
</html>
def logintest(req):
if req.method == "GET":
obj = LoginForm()
return render(req,'logintest.html',{'oo':obj})
elif req.method == "POST":
obj = LoginForm(req.POST)
if obj.is_valid():
value_right = obj.clean()
# create(**value_right) Add records to the database , Parameters are used directly **value_right
else:
return render(req,'logintest.html',{'oo':obj})

In this way, the original data can be retained after input errors .

  You need to run is_valid() Then you can clean()

ajax Implement submission verification , There is no need to implement... To retain the original input value ,ajax Do not refresh the page itself , The input value is always maintained

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.error-msg{
color: red;
font-size: 16px;
}
</style>
</head>
<body>
<form action="loginajax.html" method="post">
<p> User name :<input type="text" name="username" placeholder=" Please enter a user name "><span></span></p>
<p> User mailbox :<input type="text" name="email" placeholder=" Please enter the user email "></p><span></span></p>
<p> User password :<input type="password" name="pwd" placeholder=" Please enter the user password "></p>
{% csrf_token %}
<input type="submit" value="Form Submit ">
<input id="ajax_submit" type="button" value="Ajax Submit ">
</form>
<script src="/static/jquery-3.6.0.js"></script>
<script>
$(function () {
$("#ajax_submit").click(function () {
$.ajax({
url: "loginajax.html",
data: $('form').serialize(),
type:'POST',
success:function (arg) {
$('.error-msg').remove(); // Will have class=error-msg All tags of are deleted
var v1 = JSON.parse(arg);
//v1 It's a json object , Content :{status: false, error: '{"email": [{"message": "\\u90ae\\u7bb1\\u540d\\u683c\\u…0d\\u7b26\\u5408\\u8981\\u6c42", "code": "invalid"}]}', data: null}
// Be careful : Its error The value of is string
if(!v1.status){
var error_obj = JSON.parse(v1.error); // Right here v1.error Parse again , Because it is a string , Otherwise the following each error
$.each(error_obj,function (k,v) {
var tag = document.createElement('span');
tag.className = 'error-msg';
tag.innerHTML = v[0].message;
$("input[name='" + k +"']").after(tag);
})
}else {
location.href = 'loginajax.html';
}
}
})
})
})
</script>
</body>
</html>

front end : Get data for the form , have access to serialize() function , The obtained data can be directly used as ajax Of data Value usage .

def loginajax(req):
if req.method == "GET":
return render(req,'loginajax.html')
elif req.method == "POST":
ret = {'status':True,'error':None,'data':None}
obj = LoginForm(req.POST)
if obj.is_valid():
print(obj.clean())
print(req.POST.get('pwd'))
else:
res_str = obj.errors.as_json()
ret['status'] = False
ret['error'] = res_str
return HttpResponse(json.dumps(ret))

Back end ajax Submit directly HttpResponse Return to one json Format string , Used dumps() Method .

The above implementation , For front-end , In error information processing , Twice JSON.parse(), A little fussy .

Process the error information returned by the backend :

def loginajax(req):
if req.method == "GET":
return render(req,'loginajax.html')
elif req.method == "POST":
ret = {'status':True,'error':None,'data':None}
obj = LoginForm(req.POST)
if obj.is_valid():
print(obj.clean())
print(req.POST.get('pwd'))
else:
# res_str = obj.errors.as_json()
# ret['status'] = False
# ret['error'] = res_str
ret['status'] = False
ret['error'] = obj.errors.as_data()
# obj.errors.as_data() The value of is :{'username': [ValidationError([' The username cannot be empty '])], 'email': [ValidationError([' The format of mailbox name does not meet the requirements '])]}
# Its value Are instances of the following classes :django.core.exceptions.ValidationError
# Deserialize it once , the ValidationError([' The username cannot be empty ']) Perform a deserialization
# The final will be ret Deserialization , In this way, a total of two deserializations have been made
# ValidationError([' The username cannot be empty ']) Perform a deserialization , Because it's in ret in , So you can deserialize ret when , Use cls= Parameters , Specify a class to deserialize
return HttpResponse(json.dumps(ret,cls=JsonCustomEncode))
from django.core.validators import ValidationError
class JsonCustomEncode(json.JSONEncoder):
def default(self, field):
if isinstance(field,ValidationError):
return {'code':field.code,'message':field.message}
else:
return json.JSONEncoder.default(self,field)

front end

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.error-msg{
color: red;
font-size: 16px;
}
</style>
</head>
<body>
<form action="loginajax.html" method="post">
<p> User name :<input type="text" name="username" placeholder=" Please enter a user name "><span></span></p>
<p> User mailbox :<input type="text" name="email" placeholder=" Please enter the user email "></p><span></span></p>
<p> User password :<input type="password" name="pwd" placeholder=" Please enter the user password "></p>
{% csrf_token %}
<input type="submit" value="Form Submit ">
<input id="ajax_submit" type="button" value="Ajax Submit ">
</form>
<script src="/static/jquery-3.6.0.js"></script>
<script>
$(function () {
$("#ajax_submit").click(function () {
$.ajax({
url: "loginajax.html",
data: $('form').serialize(),
type:'POST',
success:function (arg) {
$('.error-msg').remove(); // Will have class=error-msg All tags of are deleted
var v1 = JSON.parse(arg);
//v1 It's a json object , Content :{status: false, error: '{"email": [{"message": "\\u90ae\\u7bb1\\u540d\\u683c\\u…0d\\u7b26\\u5408\\u8981\\u6c42", "code": "invalid"}]}', data: null}
// Be careful : Its error The value of is string
if(!v1.status){
// var error_obj = JSON.parse(v1.error); // Right here v1.error Parse again , Because it is a string , Otherwise the following each error
var error_obj = v1.error; // For the returned result of two deserialization at the back end ,v1.error It's a json Object , There is no need to do it again JSON.parse Parsed , a key
alert(typeof error_obj);
$.each(error_obj,function (k,v) {
// k:username or email
// v:[{},{},{},]
var tag = document.createElement('span');
tag.className = 'error-msg';
tag.innerHTML = v[0].message;
$("input[name='" + k +"']").after(tag);
})
}else {
location.href = 'loginajax.html';
}
}
})
})
})
</script>
</body>
</html>

Above is Form Basic usage of validation , Other issues needed in daily development :

- In addition to character verification and mail verification , What other verifications , Can you customize the rules yourself
- In addition to generating input label , Whether other labels can be generated
- Show default


  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved