Django 使用forms进行POST字段校验(文件上传校验)

一、前言

​ POST中有多个字段、甚至有文件上传时的验证方式。(使用forms进行验证)

​ django 中的forms不仅可以用来渲染页面表单(我不喜欢用),还可以用来校验提交的表单请求(yes, i do)。

二、具体实现

​ 此处我们假设有5个普通字段,1个文件字段。要求:采用ajax方式防川文件,并对文件格式进行校验并重命名

  • models.py

    class MainModelFile(models.Model):
        '''
        存储印花税/附加税文件
        '''
        name = models.CharField(max_length=50, verbose_name="表名")
        type = models.CharField(max_length=20, verbose_name="类型")
        belong_date = models.CharField(max_length=50, verbose_name="所属期")
        add_date = models.DateField(verbose_name="填表日期")
        add_date_time = models.DateTimeField(verbose_name="申报时间")
        content_file = models.FileField(upload_to="xxx", verbose_name="PDF文件")
    

    注:关于upload_to的路径之media的设定参考:官方网站搜索【MEDIA_URL】

  • forms.py

    class AddDataFormFileModelForm(forms.ModelForm):
        class Meta:
            model = models.MainModelFile
            fields = "__all__"
    
        def clean_content_file(self): #对于某个字段的验证使用clean_字段的方式命名
            '''
            校验文件格式并重命名文件名
            '''
            file = self.cleaned_data["content_file"]
            ext = file.name.split(".")[-1].lower()
            if ext != "pdf":
                raise forms.ValidationError("仅允许上传PDF文件")
            new_file_name = random.randint(111111111,9999999999)
            file.name = "%d.pdf"%new_file_name
    
            return file
    
  • views.py

    class AddDataView(TemplateView):
        template_name = "new_app/add_data.html"
        def get(self, request, *args, **kwargs):
            ...
        def post(self,request,*args,**kwargs): 
            check_form = AddDataFormFileModelForm(request.POST,request.FILES)
            if not check_form.is_valid():
                return JsonResponse({'message': check_form.errors, "code": 400})
            instance = check_form.save()
    
            return JsonResponse({'message': instance.name + ",保存成功","code":200})
    
  • html.py js部分

    function getCookie(name) {
        let cookieValue = null;
        if (document.cookie && document.cookie !== '') {
            const cookies = document.cookie.split(';');
            for (let i = 0; i < cookies.length; i++) {
                const cookie = cookies[i].trim();
                // Does this cookie string begin with the name we want?
                if (cookie.substring(0, name.length + 1) === (name + '=')) {
                    cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                    break;
                }
            }
        }
        return cookieValue;
    }
    
    function upload_pdf() {
        const csrftoken = getCookie('csrftoken');
        
        var form = new FormData();
        form.append("f_id", $("#f_id").val());
        form.append("image_path", $("#image_path")[0].files[0]);
        $.ajax({
            headers: {'X-CSRFToken': csrftoken},
            url: "{% url 'add_data' %}",
            type: "POST",
            data: form,
            
            processData: false,
            contentType: false,
            cache: false,
            
            success: function (result) {
                if (result.code === 200) {
                    alert_message(JSON.stringify(result.message));
                        } else {
                            console.log("success", result);
                            alert_message(JSON.stringify(result.message));
                        }
                    },
                    fail: function (result) {
                        console.log("fail",);
                        alert_message(result.info);
                    },
                    error: function (result) {
                        alert_message(result.status + ": " + result.statusText);
                    }
                });
    
            }
    

三、关于MEDIA的相关设定

  • settings.py

    ...
    MEDIA_URL = '/media/'
    MEDIA_ROOT = os.path.join(BASE_DIR,'media')
    ...
    
  • urls.py

    ...
    from django.conf import settings
    from django.conf.urls.static import static
    urlpatterns = [
        ...
    ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
    ...
    
原文地址:https://www.cnblogs.com/lisicn/p/14381839.html