zoukankan      html  css  js  c++  java
  • Ajax + Django的Form

    一、Json复习

      合格的json对象:

    ["one", "two", "three"]
    { "one": 1, "two": 2, "three": 3 }
    {"names": ["张三", "李四"] }
    [ { "name": "张三"}, {"name": "李四"} ] 

       不合格的json对象:

    { name: "张三", 'age': 32 }                    // 属性名必须使用双引号
    [32, 64, 128, 0xFFF]                          // 不能使用十六进制值
    { "name": "张三", "age": undefined }          // 不能使用undefined
    { "name": "张三",
      "birthday": new Date('Fri, 26 Aug 2011 07:13:10 GMT'),
      "getName":  function() {return this.name;}             // 不能使用函数和日期对象
    }

    二、Ajax

      AJAXAsynchronous Javascript And XML)翻译成中文就是异步的JavascriptXML”。即使用Javascript语言与服务器进行异步交互,传输的数据为XML(当然,传输的数据不只是XML)。AJAX 不是新的编程语言,而是一种使用现有标准的新方法。

    1、Ajax优点

    • AJAX使用JavaScript技术向服务器发送异步请求;
    • AJAX请求无须刷新整个页面;
    • 因为服务器响应内容不再是整个页面,而是页面中的部分内容,所以AJAX性能高; 
    • AJAX 不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行。

    2、Ajax传带文件的数据注意事项:

      (1)processData: false,

         contentType: false,

      (2)data: formData

    // AJAX提交注册的数据
        $("#reg-submit").click(function () {
            // 取到用户填写的注册数据,向后端发送AJAX请求
            var formData = new FormData();
            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", $("#id_avatar")[0].files[0]);
            formData.append("csrfmiddlewaretoken", $("[name='csrfmiddlewaretoken']").val());
    
            $.ajax({
                url: "/reg/",
                type: "post",
                processData: false,
                contentType: false,
                data: formData,
                success:function (data) {
                    if (data.status){
                        // 有错误就展示错误
                        // console.log(data.msg);
                        // 将报错信息填写到页面上
                        $.each(data.msg, function (k,v) {
                            // console.log("id_"+k, v[0]);
                            // console.log($("#id_"+k));
                            $("#id_"+k).next("span").text(v[0]).parent().parent().addClass("has-error");
                        })
    
                    }else {
                        // 没有错误就跳转到指定页面
                        location.href = data.msg;
                    }
                }
            })
        });

    3、Ajax常见应用场景

      搜索引擎根据用户输入的关键字,自动提示检索关键字。

      还有一个很重要的应用场景就是:注册时候的用户名的查重。

    其实这里就使用了AJAX技术!当文件框发生了输入变化时,使用AJAX技术向服务器发送一个请求,然后服务器会把查询到的结果响应给浏览器,最后再把后端返回的结果展示出来

    • 整个过程中页面没有刷新,只是刷新页面中的局部位置而已!
    • 当请求发出后,浏览器还可以进行其他操作,无需等待服务器的响应!

    3、Ajax实现计算机示例

    from django.conf.urls import url
    from django.contrib import admin
    from app01 import views
    
    urlpatterns = [
        url(r'^index/', views.index),
        url(r'^ajax_add/', views.ajax_add),
        url(r'^ajax_add_post/', views.ajax_add_post),
    urls.py
    from django.shortcuts import render,HttpResponse
    from . import models
    import json
    from django.core import serializers
    # Create your views here.
    
    def index(request):
        return render(request,"index.html")
    
    # get请求
    def ajax_add(request):
        i1 = request.GET.get("i1")
        i2 = request.GET.get("i2")
        i1 = int(i1)
        i2 = int(i2)
        ret = i1 + i2
        return HttpResponse(ret)
    
    #post请求
    def ajax_add_post(request):
        i1 = request.POST.get("i1")
        i2 = request.POST.get("i2")
        i1 = int(i1)
        i2 = int(i2)
        ret = i1 + i2
        return HttpResponse(ret)
    views.py
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="x-ua-compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1">
      <title>AJAX局部刷新实例</title>
    </head>
    <body>
    
    {#{% csrf_token %}#}
    <input type="text" id="i1">+
    <input type="text" id="i2">=
    <input type="text" id="i3">
    <input type="button" value="AJAX提交" id="b1">
    <input type="button" value="AJAX_POST提交" id="b3">
    <input type="button" value="呵呵哒" id="b2">
    
    <script src="/static/jquery-3.2.1.min.js"></script>
    <script src="/static/setup_ajax.js"></script>
    <script>
      $("#b1").on("click", function () {
          var i1 = $("#i1").val();
          var i2 = $("#i2").val()
        $.ajax({
            url:"/ajax_add/",
            type:"GET",
            data:{"i1":i1,"i2":i2},
            success:function(data){                 {#成功返回一个匿名函数#}
                $("#i3").val(data)
            }
        })
      })
    
        $("#b3").on("click", function () {
          var i1 = $("#i1").val();
          var i2 = $("#i2").val()
          {#var csrfToken = $("[name = 'csrfmiddlewaretoken']").val()    //找到页面上csrf_token#}
    
        $.ajax({
            url:"/ajax_add_post/",
            type:"POST",
            data:{"i1":i1,"i2":i2},
            success:function(data){                 {#成功返回一个匿名函数#}
                $("#i3").val(data)
            }
        })
      })
    
    
        $("#b2").on("click",function () {
            $.ajax({
                url:"/test/",
                type:"GET",
                success:function(data){
                    //在页面上创建一个标签
                    var imgEle = document.createElement("img");
                    imgEle.src = data;
                    //吧创建的html标签添加到文档中
                    $("#b2").after(imgEle);
                }
            })
        })
    </script>
    </body>
    </html>
    index.html

    4、Ajax实现用户注册校验示例

    from django.conf.urls import url
    from app01 import views
    urlpatterns = [
        url(r'^reg2/', views.reg2),
    ]
    urls.py
    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
        <meta name='description' content="内容" http-equiv="refresh" charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>注册</title>
        <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
    </head>
    <body>
    <div class="container">
        <div class="row">
            <div class="col-md-6 col-md-offset-3">
                <form action="/reg2/" method="post" novalidate class="form-horizontal">
                    {% csrf_token %}
                    <div class="form-group {% if form_obj.name.errors.0 %}has-error{% endif %}">
                        <label class="control-label">{{ form_obj.name.label }}</label>
                        {{ form_obj.name }}
                        <span class="help-block">{{ form_obj.name.errors.0 }}</span>
                    </div>
    
                    <div class="form-group {% if form_obj.email.errors.0 %}has-error{% endif %}">
                        <label class="control-label">{{ form_obj.email.label }}</label>
                        {{ form_obj.email }}
                        <span class="help-block">{{ form_obj.email.errors.0 }}</span>
                    </div>
    
                    <div class="form-group {% if form_obj.phone.errors.0 %}has-error{% endif %}">
                        <label class="control-label">{{ form_obj.phone.label }}</label>
                        {{ form_obj.phone }}
                        <span class="help-block">{{ form_obj.phone.errors.0 }}</span>
                    </div>
    
                    <div class="form-group {% if form_obj.pwd.errors.0 %}has-error{% endif %}">
                        <label class="control-label">{{ form_obj.pwd.label }}</label>
                        {{ form_obj.pwd }}
                        <span class="help-block">{{ form_obj.pwd.errors.0 }}</span>
                    </div>
    
                    <div class="form-group {% if form_obj.re_pwd.errors.0 %}has-error{% endif %}">
                        <label class="control-label">{{ form_obj.re_pwd.label }}</label>
                        {{ form_obj.re_pwd }}
                        <span class="help-block">{{ form_obj.re_pwd.errors.0 }}</span>
                    </div>
    
                    <div class="form-group">
                        <input type="submit" class="btn btn-primary">
                    </div>
                </form>
            </div>
        </div>
    </div>
    
    <script src="/static/jquery-3.2.1.min.js"></script>
    <script src="/static/bootstrap/js/bootstrap.min.js"></script>
    </body>
    </html>
    reg2.html
    class Userinfo(models.Model):
        name = models.CharField(max_length=32)
        pwd = models.CharField(max_length=16)
        email = models.EmailField(null=True,default="gogogo@163.com")
        phone = models.CharField(null=False,default="13902345678",max_length=11)
    mdoels.py
    from django.shortcuts import render,HttpResponse
    from . import models
    
    #      Django Form组件的使用
    from django import forms
    from django.forms import widgets
    from django.core.validators import RegexValidator           #字段校验
    from django.core.exceptions import ValidationError          #验证
    
    class RegForm(forms.Form):
        name = forms.CharField(
            label="用户名",
            max_length=16,
            # widget控制的是生成html代码相关的插件
            widget=widgets.TextInput(attrs={"class":"form-control"}),   #  <input type="email" class="form-control" id="inputEmail3" placeholder="Email">
            error_messages = {
                             "required": "该字段不能为空",
                         }
        )
        email = forms.EmailField(
            label ="邮箱",
            widget = widgets.TextInput(attrs={"class": "form-control"}),
            error_messages = {
            "required": "该字段不能为空",
            }
        )
        phone = forms.CharField(
            label="手机",
            widget=widgets.TextInput(attrs={"class": "form-control"}),
            validators=[
                RegexValidator(r'^[0-9]+$', '手机号必须是数字'),
                RegexValidator(r'^1[3-9][0-9]{9}$', '手机号格式不正确')
            ],
            error_messages={
                "required": "该字段不能为空",
            }
        )
        pwd = forms.CharField(
            label="密码",
            min_length=6,
            max_length=10,
            widget = widgets.PasswordInput(attrs={"class":"form-control"},render_value=True),
            error_messages={
                "min_length": "密码不能少于6位!",
                "required": "密码不能为空",
                "invalid": "格式错误",
                "max_length": "密码最长12位",
                }
            )
        re_pwd = forms.CharField(
            label="确认密码",
            min_length=6,
            max_length=10,
            widget=widgets.PasswordInput(attrs={"class": "form-control"}, render_value=True),
            error_messages={
                "required": "该字段不能为空",
                "invalid": "输入的两次密码不一致",
                "min_length": "密码不能少于6位!",
                "max_length": "密码最长10位!",
            }
        )
        # city = forms.ChoiceField(
        #     choices=models.City.objects.all().values_list("id","name"),
        #     label="城市",
        #     initial=1,
        #     widget=forms.widgets.Select
        # )
    
        #choices的选项可以配置从数据库中获取,但是由于是静态字段 获取的值无法实时更新,需要重写构造方法从而实现choice实时更新
        # def __init__(self,*args, **kwargs):
        #     super().__init__(*args, **kwargs)
        #     self.fields["city"].widget.choices = models.City.objects.all().values_list("id","name")
    
    
        # 定义局部钩子Hook,用来校验username字段
        def clean_name(self):
            value = self.cleaned_data.get("name")
            if "金瓶" in value:
                raise ValidationError("不符合社会主义核心价值观!")
            return value
    
        # 定义全局的钩子,用来校验密码和确认密码字段是否相同
        def clean(self):
            # 此时 通过检验的字段的数据都保存在 self.cleaned_data
            pwd = self.cleaned_data.get("pwd")
            re_pwd = self.cleaned_data.get("re_pwd")
            if pwd != re_pwd:
                self.add_error("re_pwd", ValidationError("两次密码不一致"))
                raise ValidationError("两次密码不一致")
            return self.cleaned_data
    
    def reg2(request):
        form_obj = RegForm()
    
        if request.method == "POST":
            form_obj = RegForm(request.POST)
            if form_obj.is_valid():
    
                # 校验过的数据,保存到数据库中,存在form_obj.cleaned_data(是一个字典)
                #print(form_obj.cleaned_data)  # {'name': '金瓶', 'email': 'qwe212@123.COM', 'phone': '15662286158', 'pwd': 'zxcvbnm', 're_pwd': 'zxcvbnm'}
                # ** kwargs: a=1, b=2, c=3    ==>   kwargs =  {'a': 1, 'b': 2, 'c': 3}
                # models.UserInfo.objects.create(user='rose', pwd='123456')
    
                del form_obj.cleaned_data["re_pwd"]
                models.Userinfo.objects.create(**form_obj.cleaned_data)
                return HttpResponse("登录成功")
    
        return render(request,"reg2.html",{"form_obj":form_obj})
    views.py

    5、Ajax结合SweetAlert插件示例

     点击下载  Bootstrap-sweetalert项目

    点击查看   SweetAlert for Bootstrap详情

    from django.conf.urls import url
    from app01 import views
    
    urlpatterns = [
        url(r'^sweetalert/', views.sweetalert),
    ]
    urls.py
    from django.db import models
    
    class Person(models.Model):
        name = models.CharField(max_length=32)
        age = models.IntegerField()
        birthday = models.DateField(auto_now_add=True)
        def __str__(self):
            return self.name
    models.py
    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
        <meta name='description' content="内容" http-equiv="refresh" charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>sweetalert</title>
        <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
        <link rel="stylesheet" href="/static/fontAwesome/css/font-awesome.min.css">
        <link rel="stylesheet" href="/static/sweetalert/sweetalert.css">
        <style>
            .sweet-alert > h2 {
                padding-top: 15px;
            }
        </style>
    </head>
    <body>
    <div class="container">
        <div class="panel panel-primary">
            <div class="panel-heading">
                <h3 class="panel-title">Person 管理</h3>
            </div>
            <div class="panel-body">
                <div class="bs-example" data-example-id="hoverable-table">
                    <table class="table table-hover">
                        <thead>
                        <tr>
                            <th>序号</th>
                            <th>id</th>
                            <th>name</th>
                            <th>年龄</th>
                            <th>生日</th>
                        </tr>
                        </thead>
                        <tbody>
                        {% for p in persons %}
                            <tr>
                                <td>{{ forloop.counter }}</td>
                                <td>{{ p.id }}</td>
                                <td>{{ p.name }}</td>
                                <td>{{ p.age }}</td>
                                <td>{{ p.birthday|date:"Y-m-d" }}</td>
                                <td>
                                    <button class="btn btn-danger del"><i class="fa fa-trash"> 删除</i></button>
                                </td>
                            </tr>
                        {% endfor %}
                        </tbody>
                    </table>
                </div>
            </div>
        </div>
    </div>
    
    <p>
      <button type="button" class="btn btn-primary btn-lg b1">点我</button>
    </p>
    <hr>
    
    <p>
       <input type="text" id="i1" name="name">
        <span id="e1"></span>
    </p>
    
    
    <script src="/static/jquery-3.2.1.min.js"></script>
    <script src="/static/bootstrap/js/bootstrap.min.js"></script>
    <script src="/static/sweetalert/sweetalert.min.js"></script>
    <script src="/static/setup_ajax.js"></script>
    <script>
        {#    找到删除按钮, 绑定事件#}
        // language=JQuery-CSS
        $(".del").on("#click", function () {
            var $tr_ele = $(this).parent().parent();
            var del_id = $tr_ele.children().eq(1).text();
            swal({
                    title: "你确定要删除吗?",
                    text: "一旦删除就找不回来了",
                    type: "warning",
                    showCancelButton: true,
                    showLoaderOnConfirm: true,
                    confirmButtonClass: "btn-danger",
                    confirmButtonText: "确认",
                    cancelButtonText: "取消",
                    closeOnConfirm: false
                },
            function () {              {#向后端发送删除的请求#}
                $.ajax({
                    url: "/delete/",
                    type:"post",
                    data:{"id":del_id},
                    success:function(arg){
                        swal(arg, "准备好跑路吧", "success");
                        $tr_ele.remove();
                    }
                })
            });
        })
    
        {#    找到 i1 标签,绑定事件 #}
        $("#i1").blur(function () {                  //到 i1 标签,绑定失去焦点的事件
        //$("#i1").on("input",function () {          //找到 i1 标签,绑定input实时判断 事件
            var $i1Ele = $(this);
            var name = $i1Ele.val();       // 取到input框的值
    
            $("#e1").text("");          // 将i1后面的span中的内容置为空,为了清除上次填充的内容
    
            $.ajax({
                url:"/check_user/",
                type:"post",
                data:{"name":name},
                datatype:"json",
                success:function (arg) {
                    $("#e1").text(arg).css("color","red");
                }
            })
    
        })
    </script>
    </body>
    </html>
    sweetalert.html
    from django.shortcuts import render,HttpResponse
    from . import models
    from django.core import serializers
    
    def persons(request):
        ret = models.Person.objects.all()
        # persion_list = []
        # for i in ret:
        #     persion_list.append({"name":i.name,"age":i.age})
        # print(persion_list)
        # import json
        # str = json.dumps(persion_list)
        # print(str)
        s = serializers.serialize("json",ret)
        print(s)
        return HttpResponse(s)
    
    def sweetalert(request):
        ret = models.Person.objects.all()
        return render(request,"sweetalert.html",{"persons":ret})
    
    def delete(request):
        import time
        time.sleep(3)
        del_id = request.POST.get("id")
        models.Person.objects.filter(id =del_id).delete()
        return HttpResponse("删除成功!")
    views.py

     三、Django Form和ModelForm组件

      form组件和文件上传注意事项:

    (1)form表单一定要设置 enctype = "multipart/form-data"

    (2)视图函数中,取数据:

      file_obj = request.FILES.get("name")

      file_obj.name ——> 文件名

      扩展:FileReader

    // 找到头像的input标签绑定change事件
        $("#id_avatar").change(function () {
            // 1. 创建一个读取文件的对象
            var fileReader = new FileReader();
            // 取到当前选中的头像文件
            // console.log(this.files[0]);
            // 读取你选中的那个文件
            fileReader.readAsDataURL(this.files[0]);  // 读取文件是需要时间的
            fileReader.onload = function () {
                // 2. 等上一步读完文件之后才 把图片加载到img标签中
                $("#avatar-img").attr("src", fileReader.result);
            };
        });
  • 相关阅读:
    JavaScript 继承机制设计思想
    JavaScript里的原型(prototype), 原型链,constructor属性,继承
    centos7用yum安装node.js v8.x
    sequelize 字段无法操作
    开发CLI命令行
    微信分组群发图文40152,微信分组群发图文invalid group id hint
    微信分组群发45028,微信分组群发has no masssend quota hint
    微信45028错误,微信has no masssend quota hint错误
    微信上传图文消息素材40007,invalid media_id hint
    Spring文件上传出错:java.lang.ClassCastException: org.apache.catalina.connector.Request
  • 原文地址:https://www.cnblogs.com/timetellu/p/10860209.html
Copyright © 2011-2022 走看看