如何将上载的文件存储在django中具有模型字段名称的文件夹中? [英] How do I store the uploaded file inside a folder having the name from the model field in django?

查看:44
本文介绍了如何将上载的文件存储在django中具有模型字段名称的文件夹中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用 FileField upload_to 参数,我要将用户上传的文件存储在名为 TestName 的文件夹中,即输入的测试名称由用户.我已经编写了以下代码,但是它创建了一个名为"models.CharField(max_length = 255)"的文件夹.我该如何解决?

Using the upload_to argument of FileField I want to store the file uploaded by the user in a folder named TestNameie the test name entered by the user. I've written the following code, but it creates a folder named "models.CharField(max_length=255)" instead. How can I fix this?

from django.core.validators import FileExtensionValidator
from django.db import models
from django.contrib.auth.models import User


class TestInfo(models.Model):
    TestName = models.CharField(max_length=255)
    MaxMarks = models.IntegerField()
    TimeDuration = models.IntegerField()
    PosMarks = models.IntegerField()
    NegMarks = models.IntegerField()
    InputTextFile = models.FileField(upload_to='Tests/{}/'.format(TestName),\
    validators[FileExtensionValidator(allowed_extensions['txt'])],blank=False)

    def __str__(self):
        return self.TestName

推荐答案

我认为您只是错过了一个可以在此方面提供帮助的附加功能.我现在没有时间进行特别的测试,但是您正在寻找类似的东西:

I think you just missed an additional function which could help you in this. I have not had time to test this particularly now but you are looking for something like this:

from django.core.validators import FileExtensionValidator
from django.db import models
from django.contrib.auth.models import User

def content_file_name(instance, filename):
    return "Tests/{folder}/{file}".format(folder=instance.TestName, file=filename)

class TestInfo(models.Model):
    TestName = models.CharField(max_length=255)
    MaxMarks = models.IntegerField()
    TimeDuration = models.IntegerField()
    PosMarks = models.IntegerField()
    NegMarks = models.IntegerField()
    InputTextFile = models.FileField(upload_to=content_file_name)
    validators[FileExtensionValidator(allowed_extensions['txt'])],blank=False)

    def __str__(self):
        return self.TestName

更新-使用用户名作为文件夹名称来保存上传的文件

如果要添加用户名作为将用户上传内容保存到的子文件夹名称,请按用户名将其添加到不同的子文件夹中.同时,您还要在模型中保留上载者的用户名,然后应该像下面这样制定模型.我在模型中添加了一个额外的字段,即 Uploader_info .它只是在上载时获取用户名,因此上载者用户无法对其进行编辑,它总是在上载时通过请求数据从用户表中给出.

If you want to add the username as the subfolder name where the user's uploads will be saved, into different subfolders by usernames. And at the same time you will keep the uploader's user name also in your model, then you should formulate your model a bit more like below. I added an extra field to your model as Uploader_info. It just gets the username at uploads, so it cannot be edited by the uploader user, it is just given always at uploads from your user table via request data.

在models.py中:

from django.db import models
from django.conf import settings
from django.contrib.auth.models import User
from django.core.exceptions import ValidationError

def content_file_name(instance, filename):
    return "Tests/{subfolder}/{folder}/{file}".format(subfolder=instance.Uploader_info, folder=instance.TestName, file=filename)

def validate_file_extension(value):
    if value.file.content_type != 'text/plain':
        raise ValidationError('The uploaded file must be a text file')

class TestInfo(models.Model):
    Uploader_info = models.CharField(max_length=100, editable=False, null = True)
    user = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='testinfos', on_delete=models.CASCADE, null=True)
    TestName = models.CharField(max_length=255)
    MaxMarks = models.IntegerField()
    TimeDuration = models.IntegerField()
    PosMarks = models.IntegerField()
    NegMarks = models.IntegerField()
    InputTextFile = models.FileField(upload_to=content_file_name, blank=False, validators=[validate_file_extension])        

    def __str__(self):
        template = '{0.TestName} {0.Uploader_info}'
        return template.format(self)

别忘了迁移.

重要!在模型中还添加了一个简短的功能,即在 admin.py 中注册该模型,该模型会将上传者的用户名提供给记录:

Important! Register the model in the admin.py too with a short added function which will give the uploader's username to the records:

在admin.py中:

from .models import TestInfo

class TestInfoAdmin(admin.ModelAdmin):

    def save_model(self, request, obj, form, change):
        if not change:
            obj.Uploader_info = request.user.username
        obj.save()

admin.site.register(TestInfo, TestInfoAdmin)

您当前的视图名称是提交表单的帖子,必须将其重新编写为如下形式:

Your current view name is post for the Form submission, which has to be reformulated a bit like this:

视图中,py

@login_required
def post(request):
    if request.method == 'POST':
        # create a form instance and populate it with data from the request:
        form = TestForm(request.POST, request.FILES)
        # check whether it's valid:
        if form.is_valid():
            fulltest = form.save(commit=False)
            fulltest.user = request.user
            fulltest.Uploader_info = request.user
            TestName = form.cleaned_data.get('TestName')
            File = form.cleaned_data.get('InputTextFile')
            fulltest.save()
            messages.success(request, 'Test {} Posted successfully'.format(TestName))
            return redirect('Test-Making')
        else:
            parameters = {
              'form': form,                   
              'error': form.errors.as_ul()
            }
            return render(request, 'Test/post.html', parameters)

    # if a GET (or any other method) we'll create a blank form
    else:
        form = TestForm()
        return render(request, 'Test/post.html', {'form': form})

和您在 forms.py 中的表单很简单:

and your Form in forms.py is simply:

class TestForm(forms.ModelForm):
    class Meta:
        model = TestInfo
        fields = ('TestName', 'MaxMarks', 'TimeDuration', 'PosMarks', 'NegMarks', 'InputTextFile')

就是这样.如果您的表格还可以,则上面的代码将在我成功测试后正常工作.

And that's about it. If your Form is OK then the above will work as I tested that successfully.

这篇关于如何将上载的文件存储在django中具有模型字段名称的文件夹中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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