Как сохранить загруженный файл в папке с именем из поля модели в django? - PullRequest
0 голосов
/ 25 февраля 2019

Используя аргумент upload_to FileField Я хочу сохранить файл, загруженный пользователем, в папку с именем TestName, т. Е. Имя теста, введенное пользователем.Я написал следующий код, но вместо этого он создает папку с именем "models.CharField (max_length = 255)".Как я могу это исправить?

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

1 Ответ

0 голосов
/ 25 февраля 2019

Я думаю, вы просто пропустили дополнительную функцию, которая могла бы помочь вам в этом.У меня не было времени, чтобы проверить это особенно сейчас, но вы ищете что-то вроде этого:

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 .Он просто получает имя пользователя при загрузке, поэтому он не может быть отредактирован пользователем, добавившим его, просто он всегда дается при загрузке из вашей пользовательской таблицы через данные запроса.

в 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 , добавив короткую добавленную функцию, которая будет давать имя пользователя, добавляющее записи, в записи:

в 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)

Ваше текущее имя представления post для отправки формы, которое должно быть переформулировано примерно так:

в представлениях, 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 просто:

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

И это все.Если с вашей формой все в порядке, то вышеприведенное сработает, поскольку я успешно ее проверил.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...