Django中的文件上传(利用class-based view)
admin
2023-07-31 01:44:57
0

背景介绍

在Django的官网上有专门介绍如何处理文件上传的文档,其中说到了如何利用model来处理文件上传的场景。但是,在Django中最快速的开发方式是利用class-based views来进行开发。所以,我自己整理了一下如何利用class-based views来处理文件上传的场景,特此记录。


model

既然是数据驱动的web,自然先要有model。

from django.db import models
from django.contrib.auth.models import User
from django.conf import settings
import os

_roles_path = os.path.join(_base_path, \'roles\')


def var_dir(instance, filename):
    return os.path.join(_roles_path, instance.name, \'vars\', filename)


def task_dir(instance, filename):
    return os.path.join(_roles_path, instance.name, \'tasks\', filename)


class Roles(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=50)
    creator = models.ForeignKey(User)
    createDatetime = models.DateTimeField(auto_now_add=True)
    directory = models.FilePathField(path=_roles_path, match=\'*.yml\', recursive=True, max_length=200)
    tasks = models.FileField(upload_to=task_dir, blank=False)
    vars = models.FileField(upload_to=var_dir)

    def __unicode__(self):
        return u\'%s\' % self.name

上面用到了动态的upload_to,对应每个FileField都提供不同的上传路径。因为upload_to可以接受一个callable的对象,所以我尝试过把lambda赋值给upload_to,但是在测试中发现,给upload_to赋值为lambda表达式是会报错的ValueError: Cannot serialize function: lambda。应该可以尝试利用闭包的方式来给upload_to赋值,以解决多种动态路径的需求。

经过后续的测试发现,闭包也是不支持的

def _roles_subdir(roles_path, subdir):
    def wrapper(instance, filename):
        return os.path.join(roles_path, instance.name, subdir, filename)
    return wrapper

Please note that due to Python 2 limitations, you cannot serialize unbound method functions (e.g. a method declared
and used in the same class body). Please move the function into the main module body to use migrations.
For more information, see
https://docs.djangoproject.com/en/1.7/topics/migrations/#serializing-values

view

本例中使用Django提供的CreateView。在实际的使用中,可以针对于自己的应用场景选择CreateView、UpdateView。

from django.views.generic.edit import FormView, CreateView
from django.views.decorators.csrf import csrf_exempt
from django.core.urlresolvers import reverse_lazy

class UploadRolesFormView(CreateView):
    template_name = \'app/upload_roles.html\'
    model = Roles
    fields = [\'name\', \'tasks\', \'vars\']
    success_url = reverse_lazy(\'app:index\')

    #临时去掉CSRF保护,千万别学我!
    @csrf_exempt
    def dispatch(self, request, *args, **kwargs):
        return super(UploadRolesFormView, self).dispatch(request, *args, **kwargs)

    #override
    def form_valid(self, form):
        #在form中加入user对象存入model
        form.instance.creator = self.request.user
        return super(UploadRolesFormView, self).form_valid(form)

template


    
        upload
        
        
    

    
        

url

在app的urls.py中加入一条对应的url规则:

url(r\'^upload/$\', views.UploadRolesFormView.as_view(), name=\'rolesUpload\'),

这样,就可以利用Django最方便的class-based views开处理文件上传的场景了。

相关内容

热门资讯

Mobi、epub格式电子书如... 在wps里全局设置里有一个文件关联,打开,勾选电子书文件选项就可以了。
500 行 Python 代码... 语法分析器描述了一个句子的语法结构,用来帮助其他的应用进行推理。自然语言引入了很多意外的歧义,以我们...
定时清理删除C:\Progra... C:\Program Files (x86)下面很多scoped_dir开头的文件夹 写个批处理 定...
scoped_dir32_70... 一台虚拟机C盘总是莫名奇妙的空间用完,导致很多软件没法再运行。经过仔细检查发现是C:\Program...
65536是2的几次方 计算2... 65536是2的16次方:65536=2⁶ 65536是256的2次方:65536=256 6553...
小程序支付时提示:appid和... [Q]小程序支付时提示:appid和mch_id不匹配 [A]小程序和微信支付没有进行关联,访问“小...
pycparser 是一个用... `pycparser` 是一个用 Python 编写的 C 语言解析器。它可以用来解析 C 代码并构...
微信小程序使用slider实现... 众所周知哈,微信小程序里面的音频播放是没有进度条的,但最近有个项目呢,客户要求音频要有进度条控制,所...
Apache Doris 2.... 亲爱的社区小伙伴们,我们很高兴地向大家宣布,Apache Doris 2.0.0 版本已于...
python清除字符串里非数字... 本文实例讲述了python清除字符串里非数字字符的方法。分享给大家供大家参考。具体如下: impor...