使用动态路径将文件上传到Django [英] Upload file to Django with dynamic path

查看:46
本文介绍了使用动态路径将文件上传到Django的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试上传文件并整理媒体文件夹中的目录结构.具体来说,我希望上载基于模型中的值之一创建子文件夹.我面临的问题是,在视图中,我向实例添加了信息(在我的示例代码中,这是相关的 profile ).我想将此信息用于子文件夹,但是在上载之后的保存之前,该信息在我的模型中不存在...

I am trying to upload files and organise the directory structure in the media folder. In specific I want the upload to create subfolders basis one of the values in the model. The issue I face is that in the view I add information to the instance (in my example code this is the relevant profile). I would like to use this information for the subfolder, but it does not exist in my model until the save which is after the upload...

将信息放入 Upload 以便可以创建子文件夹的合适方法是什么?

What would be the appropriate approach to get the information into Upload so that the subfolder can be created?

谢谢

型号:

class Upload(models.Model):
    file = models.FileField(upload_to="upload/")
    profile = models.ForeignKey(Profile, blank=True, null=True)

    def get_upload_to(self, field_attname):
        return 'upload/%d' % self.profile

查看:

def profile(request, profile_slug):
    profile = Profile.objects.get(slug=profile_slug)
    context_dict['profile'] = profile
    if request.method=="POST":
            for file in request.FILES.getlist('file'):
                    upload = UploadForm(request.POST, request.FILES)
                    if upload.is_valid():
                            newupload = upload.save(commit=False)
                            newupload.profile = profile
                            newupload.save()
    else:
        pass

    upload=UploadForm()
    context_dict['form'] = upload

    return render(request, 'app/profile.html', context_dict)

解决方案,感谢xyres:

SOLUTION, thanks to xyres:

型号:

def get_upload_to(instance, filename):
    return 'upload/%s/%s' % (instance.profile, filename)

class Upload(models.Model):
    file = models.FileField(upload_to=get_upload_to)
    profile = models.ForeignKey(Profile, blank=True, null=True)

查看:

def profile(request, profile_slug):
    profile = Profile.objects.get(slug=profile_slug)
    context_dict['profile'] = profile
    if request.method=="POST":
        upload = UploadForm(request.POST, request.FILES)
        if upload.is_valid():
            for f in request.FILES.getlist('file'):
                Upload.objects.create(file=f, profile=profile)
        return redirect(reverse('profile')
    else:
        pass

    return render(request, 'app/profile.html', context_dict)

推荐答案

将返回上载路径的函数带有2个参数,即: instance filename .您需要在此类之外定义此函数,并将此函数提供给 upload_to 选项.

The function which will return the upload path takes 2 arguments, namely: instance and filename. You'll need to define this function outside this class and supply this function to upload_to option.

这是您需要重写代码的方式:

This is how you need to rewrite your code:

def get_upload_to(instance, filename):
    return 'upload/%d/%s' % (instance.profile, filename)


class Upload(models.Model):
    file = models.FileField(upload_to=get_upload_to)
    profile = models.ForeignKey(Profile, blank=True, null=True)

如果您想知道为什么无法在类内部定义 get_upload_to ,以下是您很可能会遇到的错误:

In case you're wondering why get_upload_to can't be defined inside the class, below is the error you'll most likely get:

ValueError:在categ.models中找不到函数get_upload_to.

ValueError: Could not find function get_upload_to in categ.models.

请注意,由于Python 2的限制,您无法序列化未绑定的方法函数(例如,在同一类主体中声明和使用的方法).请将该功能移到主模块主体中以使用迁移.

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.

这篇关于使用动态路径将文件上传到Django的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆