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文件夹:

    ##### 愿你一寸一寸地攻城略地,一点一点地焕然一新 #####
  • 相关阅读:
    [转]Code! MVC 5 App with Facebook, Twitter, LinkedIn and Google OAuth2 Sign-on (C#)
    [转]OAuth 2.0
    SpringMVC之七:SpringMVC中使用Interceptor拦截器
    多数据源问题--Spring+Ibatis 访问多个数据源(非分布式事务)
    读写分离
    SVN中检出(check out) 和 导出(export) 的区别
    Hbase之三:Hbase Shell使用入门
    hadoop之一:概念和整体架构
    Twitter Storm如何保证消息不丢失
    Twitter Storm: storm的一些常见模式
  • 原文地址:https://www.cnblogs.com/johnyang/p/13699518.html
Copyright © 2011-2022 走看看