Django前后端交互&数据验证

一、前端--->后端

1.form表单

复制代码
 <form method="post" action="/test/?a=1&b=2">

         {% csrf_token %}

         <input type="text" name="user">
         <input type="submit" value="提交">
 </form>

#后台可以通过request.POST.get('user')获取输入框里面的内容
#后台可以通过request.GET.get('a')获取url?后面的内容
复制代码

2.通过正则路由&重命名路由传值

传送门

3.Ajax

复制代码
function AjaxSend(){
             nid=$('#kant').val()#获取ID为kant的值
             $.ajax(
             {
                url:'/modal_add_class/',
                type:'POST',
                data:{'title':$('#title_1').val(),'nid':nid},   #获取ID为title_1的值

                success:function(data){
                   console.log(data);   #F12处显示data
                   if(data=="ok")
                   {
                   alert('添加成功')
                   location.href='/123/';  #跳转到网页
                   }
                   else
                   {
                     $('#errormsg').text(data);  #
                   }
                }})}

#后台可以通过request.POST.get('title')取值
复制代码

 

二、后端--->前端

1.传给页面

复制代码
from django.shortcuts import HttpResponse,render,redirect


return render(request, 'add_teacher_class.html',{'class_list':class_list})
#前端接受可以用{{class_list}}  并且可以使用循环判断什么的.出其中的内容


#补充
#return HttpResponse('ok')
#return  redirect('/abc/')转到响应的path或者写http地址也行
复制代码

 

2.传给Ajax(字典)

复制代码
    ret = {'status': True, 'message': None}
    try:
        name=request.POST.get('name')
        classId=request.POST.get('classId')
        print(name, classId)
        modify("insert into student(name,class_id)  values(%s,%s)", [name, classId])

    except Exception as e:
        ret['status'] = False
        ret['message'] = str(e)  # 异常对象的内容以字符串格式拿到


    return HttpResponse(json.dumps(ret))


#Ajax收JSON的时候要加上一条 dataType:"JSON",自动转换类型
View Code
复制代码

 


三、数据验证(让用户需要输入特定的格式)

(首先造一个相关类继承Form)

复制代码
from django.forms import Form,fields,widgets

class FormLogin(Form):
         username=fields.CharField(min_length=6,max_length=18,required=True,
                                 error_messages={
                                     'required':'用户名不能为空',
                                     'min_length':'最小长度为6',
                                     'max_length':'最大长度18',
                                 }
                                 )
password = fields.CharField(min_length=6, max_length=18, required=True,
                                   error_messages={
                                       'required': '密码不能为空',
                                       'min_length': '最小长度为6',
                                       'max_length': '最大长度18',
                                   }
                                   )
View Code
复制代码

创建Form类时,主要涉及到 【字段】 和 【插件】,字段用于对用户请求数据的验证,插件用于自动生成HTML;

内置字段:

复制代码
  1 Field
  2     required=True,               是否允许为空
  3     widget=None,                 HTML插件
  4     label=None,                  用于生成Label标签或显示内容
  5     initial=None,                初始值
  6     help_text='',                帮助信息(在标签旁边显示)
  7     error_messages=None,         错误信息 {'required': '不能为空', 'invalid': '格式错误'}
  8     show_hidden_initial=False,   是否在当前插件后面再加一个隐藏的且具有默认值的插件(可用于检验两次输入是否一直)
  9     validators=[],               自定义验证规则
 10     localize=False,              是否支持本地化
 11     disabled=False,              是否可以编辑
 12     label_suffix=None            Label内容后缀
 13  
 14  
 15 CharField(Field)
 16     max_length=None,             最大长度
 17     min_length=None,             最小长度
 18     strip=True                   是否移除用户输入空白
 19  
 20 IntegerField(Field)
 21     max_value=None,              最大值
 22     min_value=None,              最小值
 23  
 24 FloatField(IntegerField)
 25     ...
 26  
 27 DecimalField(IntegerField)
 28     max_value=None,              最大值
 29     min_value=None,              最小值
 30     max_digits=None,             总长度
 31     decimal_places=None,         小数位长度
 32  
 33 BaseTemporalField(Field)
 34     input_formats=None          时间格式化   
 35  
 36 DateField(BaseTemporalField)    格式:2015-09-01
 37 TimeField(BaseTemporalField)    格式:11:12
 38 DateTimeField(BaseTemporalField)格式:2015-09-01 11:12
 39  
 40 DurationField(Field)            时间间隔:%d %H:%M:%S.%f
 41     ...
 42  
 43 RegexField(CharField)
 44     regex,                      自定制正则表达式
 45     max_length=None,            最大长度
 46     min_length=None,            最小长度
 47     error_message=None,         忽略,错误信息使用 error_messages={'invalid': '...'}
 48  
 49 EmailField(CharField)      
 50     ...
 51  
 52 FileField(Field)
 53     allow_empty_file=False     是否允许空文件
 54  
 55 ImageField(FileField)      
 56     ...
 57     注:需要PIL模块,pip3 install Pillow
 58     以上两个字典使用时,需要注意两点:
 59         - form表单中 enctype="multipart/form-data"
 60         - view函数中 obj = MyForm(request.POST, request.FILES)
 61  
 62 URLField(Field)
 63     ...
 64  
 65  
 66 BooleanField(Field)  
 67     ...
 68  
 69 NullBooleanField(BooleanField)
 70     ...
 71  
 72 ChoiceField(Field)
 73     ...
 74     choices=(),                选项,如:choices = ((0,'上海'),(1,'北京'),)
 75     required=True,             是否必填
 76     widget=None,               插件,默认select插件
 77     label=None,                Label内容
 78     initial=None,              初始值
 79     help_text='',              帮助提示
 80  
 81  
 82 ModelChoiceField(ChoiceField)
 83     ...                        django.forms.models.ModelChoiceField
 84     queryset,                  # 查询数据库中的数据
 85     empty_label="---------",   # 默认空显示内容
 86     to_field_name=None,        # HTML中value的值对应的字段
 87     limit_choices_to=None      # ModelForm中对queryset二次筛选
 88      
 89 ModelMultipleChoiceField(ModelChoiceField)
 90     ...                        django.forms.models.ModelMultipleChoiceField
 91  
 92  
 93      
 94 TypedChoiceField(ChoiceField)
 95     coerce = lambda val: val   对选中的值进行一次转换
 96     empty_value= ''            空值的默认值
 97  
 98 MultipleChoiceField(ChoiceField)
 99     ...
100  
101 TypedMultipleChoiceField(MultipleChoiceField)
102     coerce = lambda val: val   对选中的每一个值进行一次转换
103     empty_value= ''            空值的默认值
104  
105 ComboField(Field)
106     fields=()                  使用多个验证,如下:即验证最大长度20,又验证邮箱格式
107                                fields.ComboField(fields=[fields.CharField(max_length=20), fields.EmailField(),])
108  
109 MultiValueField(Field)
110     PS: 抽象类,子类中可以实现聚合多个字典去匹配一个值,要配合MultiWidget使用
111  
112 SplitDateTimeField(MultiValueField)
113     input_date_formats=None,   格式列表:['%Y--%m--%d', '%m%d/%Y', '%m/%d/%y']
114     input_time_formats=None    格式列表:['%H:%M:%S', '%H:%M:%S.%f', '%H:%M']
115  
116 FilePathField(ChoiceField)     文件选项,目录下文件显示在页面中
117     path,                      文件夹路径
118     match=None,                正则匹配
119     recursive=False,           递归下面的文件夹
120     allow_files=True,          允许文件
121     allow_folders=False,       允许文件夹
122     required=True,
123     widget=None,
124     label=None,
125     initial=None,
126     help_text=''
127  
128 GenericIPAddressField
129     protocol='both',           both,ipv4,ipv6支持的IP格式
130     unpack_ipv4=False          解析ipv4地址,如果是::ffff:192.0.2.1时候,可解析为192.0.2.1, PS:protocol必须为both才能启用
131  
132 SlugField(CharField)           数字,字母,下划线,减号(连字符)
133     ...
134  
135 UUIDField(CharField)           uuid类型
136     ...
View Code
复制代码

内置插件:

复制代码
 1 Select
 2 TextInput(Input)
 3 NumberInput(TextInput)
 4 EmailInput(TextInput)
 5 URLInput(TextInput)
 6 PasswordInput(TextInput)
 7 HiddenInput(TextInput)
 8 Textarea(Widget)
 9 DateInput(DateTimeBaseInput)
10 DateTimeInput(DateTimeBaseInput)
11 TimeInput(DateTimeBaseInput)
12 CheckboxInput
13 NullBooleanSelect
14 SelectMultiple
15 RadioSelect
16 CheckboxSelectMultiple
17 FileInput
18 ClearableFileInput
19 MultipleHiddenInput
20 SplitDateTimeWidget
21 SplitHiddenDateTimeWidget
22 SelectDateWidget
View Code
复制代码

常用选择插件:

复制代码
 1 # 单radio,值为字符串
 2 # user = fields.CharField(
 3 #     initial=2,
 4 #     widget=widgets.RadioSelect(choices=((1,'上海'),(2,'北京'),))
 5 # )
 6  
 7 # 单radio,值为字符串
 8 # user = fields.ChoiceField(
 9 #     choices=((1, '上海'), (2, '北京'),),
10 #     initial=2,
11 #     widget=widgets.RadioSelect
12 # )
13  
14 # 单select,值为字符串
15 # user = fields.CharField(
16 #     initial=2,
17 #     widget=widgets.Select(choices=((1,'上海'),(2,'北京'),))
18 # )
19  
20 # 单select,值为字符串
21 # user = fields.ChoiceField(
22 #     choices=((1, '上海'), (2, '北京'),),
23 #     initial=2,
24 #     widget=widgets.Select
25 # )
26  
27 # 多选select,值为列表
28 # user = fields.MultipleChoiceField(
29 #     choices=((1,'上海'),(2,'北京'),),
30 #     initial=[1,],
31 #     widget=widgets.SelectMultiple
32 # )
33  
34  
35 # 单checkbox
36 # user = fields.CharField(
37 #     widget=widgets.CheckboxInput()
38 # )
39  
40  
41 # 多选checkbox,值为列表
42 # user = fields.MultipleChoiceField(
43 #     initial=[2, ],
44 #     choices=((1, '上海'), (2, '北京'),),
45 #     widget=widgets.CheckboxSelectMultiple
46 # )
View Code
复制代码

intfield和charfield都继承field;     e-mailfiled继承charfield    field里面有的‘方法’ 他们都可以使用,本质上验证就是

 

form表单验证

复制代码
#-----------方法一:提交后数据不保存----------
#自己写<input>框+{{obj.errors.password.0}}
#收到POST请求
        obj=FormLogin(request.POST)
        if obj.is_valid():#匹配通过的话
            print(obj.cleaned_data)#做一些操作
        else:
        return render(request, 'form.html',{'obj':obj} )



#-----------方法二:提交后数据保存----------
#自动生成各种框{{obj.username}}+{{obj.errors.password.0}}
#收到get请求:
obj = RegisterForm()  # 没有传任何值,生成类里面所有规定的‘框框’
return render(request, 'register.html', {'obj': obj}, )#与页面obj会和
#收到post请求:
       (跟上面的一样)
        obj=FormLogin(request.POST)
        if obj.is_valid():#匹配通过的话
            print(obj.cleaned_data)#做一些操作
        else:
        return render(request, 'form.html',{'obj':obj} )


ps:
print(obj.cleaned_data)  #输出正确内容(字典)
obj = StuForm(data=row)  #row为编辑时需要的一行数据(字典格式),页面显示的时候自动匹配
#编辑时要显示编辑的内容,可通过正则路由传递参数

 if request.method == 'GET':
        row = models.Student.objects.filter(id=nid).values('name','email','age','cls_id').first()  #row是一个{}
        #obj = StuForm(data={'name': row.name,'email':row.email,'age':row.age,'cls_id':nid})  # 页面显示  data的时候自动校验
        obj = StuForm(data=row)  # 页面显示  data的时候自动校验
        # obj=ClassForm(initial={'title':row.title})  #不校验
        return render(request, 'edit_student.html', {'nid': nid, 'row': row, 'obj': obj})
View Code
复制代码

 Ajax验证(推荐)

复制代码
//自己写form表单  <input>//不用再页面使用{{obj.username}}等
//直接用Ajax提交表单:
 function abc(){
            $('.c1').remove();
           $.ajax(

             {

                url:'/form_login_ajax/',
                type:'POST',
                data:$('#f1').serialize(), //ID为f1的form表单内所有数据

                dataType:"JSON",   //将序列化的json转化为对象
                success:function(data){
                   console.log(data);
                   if(data.status){

                   }else{
                     $.each(data.msg,function(index,value){   //对data.msg进行循环
                        console.log(index,value);             //取其index(key),value
                        var tag=document.createElement('span');  //创建一个tag标签
                        tag.innerHTML=value[0];    //取value第一个值
                        console.log(value[0]);
                        console.log(tag);
                        tag.className='c1';  //给标签加一个样式  等到下次来的时候给它删除(避免累加提示错误)
                        $('#f1').find('input[name="'+index+'"]').after(tag);  //input[name=" user "]'   ,不能有多余的空格
                        //找到id为f1的表格,下面找到input name=x,加入tag标签
                        })
                   }

                                   }

                })
              }


//后台接收后:

   import json
        ret={'status':True, 'msg':None}
        obj = FormLogin(request.POST)
        if obj.is_valid():  # 去匹配
            print(obj.cleaned_data)  # 正确的信息
            #return redirect('http://www.baidu.com')
        else:
            print(obj.errors)

            # v=json.dumps(obj.errors,ensure_ascii=False)#通过json 对它序列化,并且能print出来
            # print(v)
            ret['status']=False
            ret['msg']=obj.errors
        v=json.dumps(ret,ensure_ascii=False)
        print(v)
        return HttpResponse(v)  #也能返回render(本质还是HttpResponse),但是这里返回这个比较好,弄个json.domp字典返回最好
           # return render(request, 'form_login.html', {'obj': obj, 'user': user, 'pwd': pwd})
        #完成验证和提示错误,但是无法保留Form表单上次输入内容
View Code
复制代码

 自定义验证规则

复制代码
from django.forms import Form
from django.forms import widgets
from django.forms import fields
from django.core.validators import RegexValidator
 
class MyForm(Form):
    user = fields.CharField(
        validators=[RegexValidator(r'^[0-9]+$', '请输入数字'), RegexValidator(r'^159[0-9]+$', '数字必须以159开头')],
    )
View Code
复制代码
复制代码
import re
from django.forms import Form
from django.forms import widgets
from django.forms import fields
from django.core.exceptions import ValidationError


# 自定义验证规则
def mobile_validate(value):
    mobile_re = re.compile(r'^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$')
    if not mobile_re.match(value):
        raise ValidationError('手机号码格式错误')
 
 
class PublishForm(Form):
 
 
    title = fields.CharField(max_length=20,
                            min_length=5,
                            error_messages={'required': '标题不能为空',
                                            'min_length': '标题最少为5个字符',
                                            'max_length': '标题最多为20个字符'},
                            widget=widgets.TextInput(attrs={'class': "form-control",
                                                          'placeholder': '标题5-20个字符'}))
 
 
    # 使用自定义验证规则
    phone = fields.CharField(validators=[mobile_validate, ],
                            error_messages={'required': '手机不能为空'},
                            widget=widgets.TextInput(attrs={'class': "form-control",
                                                          'placeholder': u'手机号码'}))
 
    email = fields.EmailField(required=False,
                            error_messages={'required': u'邮箱不能为空','invalid': u'邮箱格式错误'},
                            widget=widgets.TextInput(attrs={'class': "form-control", 'placeholder': u'邮箱'}))

#attrs={}是讲网页中的对应key的值替换成后面的值
View Code
复制代码

 传送门

posted @   磕伴  阅读(411)  评论(0编辑  收藏  举报
编辑推荐:
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
阅读排行:
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 字符编码:从基础到乱码解决
· 提示词工程——AI应用必不可少的技术
点击右上角即可分享
微信分享提示