zoukankan      html  css  js  c++  java
  • Django中的Ajax表单提交与文件上传

    Django中Ajax表单提交

    Ajax是以一种与服务器交换数据的技术,可以在不重载整个页面的情况下更新网页的一部分。它也可以运用在Django项目的表单中,与普通的views函数不一样的是:表单所在的网页上必须有JavaScript脚本,该脚本一方面对提交数据给view方法,另一方面根据view返回的response对现有的页面进行调整。

    下面是一个简单的例子,通过这个例子,总结其步骤和需要注意的地方。

    • 首先是html
    # base.html
    <!DOCTYPE html>
    <html lang="">
    <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>Title Page</title>
        <!-- Bootstrap CSS -->
        <link href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
        <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
        <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
        <!--[if lt IE 9]>
        <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.3/html5shiv.js"></script>
        <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
        <![endif]-->
        <!-- jQuery -->
        <script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>
    <!-- Bootstrap JavaScript -->
    <script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
    </head>
    <body>
    {% block body_block %}
    {% endblock %}
     </body>
    </html>
    
    # testAjax.html
    {% extends 'base.html' %}
    {% block body_block %}
    <h4>FeedBack</h4>
    <div class="row">
        <div id="feedbackmessage">
            Hell
        </div>
    </div>
    <form  method="POST" id="feedbackform" action='{% url "testapp:feedback" %}'>
        {% csrf_token %}
        <div class="row">
            <div class="col-md-12">
                {{ form.comment }}
            </div>
        </div>
        {{ form.name.as_hidden }}
        {{ form.email.as_hidden }}
        {{ form.gender.as_hidden }}
        <input type="submit" value="Submit feedback" class="btn btn-primary">
    </form>
    
    <script>
        $(document).ready(function(){
            $('#feedbackform').submit(function(event){
                event.preventDefault()
                $.ajax({data:$(this).serialize(),
                type:$(this).attr('method'),
                url:$(this).attr('action'),
                success:function(response){
                    console.log(response);
                    if (response['success']){
                        $('#feedbackmessage').html('<div class="alert alert-success"> Successsfully sent feedback</div>');
                        $('#feedbackform').addClass('hidden');
                    };
                    if (response['error']){
                        $('#feedbackmessage').html("<div class='alert alert-danger'>"+
                        response['error']['comment']+"</div>");
                    }
                },
                error:function (request,status,error){
                    console.log(request.responseText);
                }
                })
            })
        })
    </script>
    {% endblock %}
    

    这里需要注意的是在JQuery下的Ajax的脚本中,event.preventDefault方法必须要调用,因为这个方法意味着阻止元素发生默认行为(详见https://www.runoob.com/jquery/event-preventdefault.html),如果没有阻止的话,ajax技术就没有办法运用,在提交了表单后,页面直接返回view方法返回的response页面,而不会根据ajax的逻辑来修改页面。(ajax简介:https://www.runoob.com/jquery/jquery-ref-ajax.html

    • url
    #主urls.py
    from django.contrib import admin
    from django.urls import include
    from django.urls import path
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('testapp/',include('testapp.urls',namespace='testapp')) #定义命名空间
    
    ]
    
    #app中的urls.py
    from django.conf.urls import url 
    from testapp import views 
    from django.views.generic import TemplateView
    app_name='testapp' #定义命名空间
    urlpatterns=[
        url(r'^testDebug',views.testDebug,name='testDebug'),
        url(r'^feedback/$',views.feedback,name='feedback'),
    ]
    
    • views.py
    def feedback(request):
        if request.POST:
            form=ContactForm(request.POST)
            if form.is_valid():
                return JsonResponse({'success':True})
            else:
                return JsonResponse({'error':form.errors})
        form=ContactForm(initial={'email':'784@qq.com','name':'yy','gender':'a'})
        return render(request,'testapp/testAjax.html',{'form':form})
    
    • forms.py
    from django import forms 
    class ContactForm(forms.Form):
        name=forms.CharField(required=False)
        email=forms.EmailField(label='Your Email')
        comment=forms.CharField(widget=forms.Textarea)
        gender=forms.ChoiceField(choices=(('a','male'),('b','female'),('c','人妖')))
        def clean_name(self):
            name=self.cleaned_data.get('name','')
            if 'y' not in name:
                raise forms.ValidationError('y not in name')
            return name 
    
    image-20200920121757006

    填写,提交后:

    image-20200920122132177

    Django中文件上传

    与普通的view函数及

    不一样的是:bound form中还需要传入request.FILES, html中的中还应该有enctype='multipart/form-data',该属性规定在发送到服务器之前应该如何对表单数据进行编码,'multipart/form-data'即不对字符进行编码,在使用包含文件上传控件的表单中必须使用该值。

    • html
    {% extends 'base.html' %}
    {% block body_block %}
    <form method="POST" enctype="multipart/form-data">
        {% csrf_token %}
        <ul>
            {{ form.as_ul }}
        </ul>
        <input type="submit" value="submit img/vedio" class="btn btn-primary">
    </form>
    {% endblock %}
    
    • forms.py
    class SharingForm(forms.Form):
        video=forms.FileField()
        photo=forms.FileField(widget=forms.ClearableFileInput(attrs={'multiple':True}))
        
    
    • views.py
    from django.conf import settings 
    def save_upload_file_to_media_root(f):
        with open('%s/%s'%(settings.MEDIA_ROOT,f.name),'wb+') as destination:
            for chunk in f.chunks():
                destination.write(chunk)
    
    def uploadFile(request):
        if request.method=='POST':
            form=forms.SharingForm(request.POST,request.FILES)
            if form.is_valid():
                for field in request.FILES.keys():
                    for formfile in request.FILES.getlist(field):
                        save_upload_file_to_media_root(formfile)
            return HttpResponse('OK,Upload successfully')
        else:
            form=forms.SharingForm()
        return render(request,'banners/upload.html',{'form':form})
    

    效果:

    提交:

    查看项目下的media文件夹:

    ##### 愿你一寸一寸地攻城略地,一点一点地焕然一新 #####
  • 相关阅读:
    Python中所有的关键字
    关于selenium的8种元素定位
    对提示框的操作
    selenium+webservice进行百度登录
    MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk. Commands that may modify the data set are disabled...报错解决
    Vue中使用echarts
    npm WARN deprecated request@2.88.2: request has been deprecated, see https://github.com/request/request/issues/3142解决方法
    插入排序
    冒泡排序优化
    roject 'org.springframework.boot:spring-boot-starter-parent:XXX' not found 解决
  • 原文地址:https://www.cnblogs.com/johnyang/p/13699518.html
Copyright © 2011-2022 走看看