Невозможность загрузки файлов в django через веб-формы

Я пытаюсь создать сайт на django, похожий на сайт Udemy или Coursera. Я пытаюсь реализовать функцию, позволяющую пользователям добавлять курсы.

Вот мое мнение по поводу добавления курса:

def create_course(request):
    form = CreateCourseForm()

    if request.method == 'POST':
        form = CreateCourseForm(request.POST)
        if form.is_valid():
            new_course = form.save(commit=False)
            new_course.instructor = request.user
            new_course.save()
            return redirect('home')
    return render(request, 'courses/create.html',{'form':form})

Вот моя форма:

class CreateCourseForm(forms.ModelForm):
    class Meta:
        model = Course
        fields = ('name','video','description','category',)

Моя модель курса:

class Course(models.Model): 
    name = models.CharField(max_length=200)
    instructor = models.ForeignKey(User, on_delete=models.CASCADE)
    video = models.FileField(upload_to='videos/')
    description = models.TextField()
    category = models.ForeignKey(Category, on_delete=models.CASCADE)

    def __str__(self):
        return self.name

    

И наконец, моя веб-форма:

{% extends "base.html" %}
{% load crispy_forms_tags %}

{% block content %}
<h1>Create a Course</h1>
<hr>
<form method="post" enctype="multipart/form-data">
    {% csrf_token %}
    {{ form|crispy }}
    <button class="btn btn-sm btn-outline-primary" type="submit">Create Course</button>
</form>
{% endblock %}

Проблема, с которой я столкнулся, заключается в том, что когда я пытаюсь создать курс, поле видео показывает ошибку "Это поле обязательно", даже когда я загрузил видео.

Я попробовал немного поискать и выяснил, что требуется добавить enctype="multipart/form-data" в форму, но даже это не решило мою проблему

Может ли кто-нибудь помочь мне здесь?

Вам нужно передать request.POST и request.FILES в форму, так:

def create_course(request):
    form = CreateCourseForm()

    if request.method == 'POST':
        #                             add request.FILES ↓
        form = CreateCourseForm(request.POST, request.FILES)
        # …
    return render(request, 'courses/create.html',{'form':form})

Если вы передаете только request.POST, вы передаете только те элементы формы, которые не являются загрузкой файлов. В этом случае в поля формы действительно будет добавлена ошибка, говорящая, что форма требует данных для этих полей.

Как сказал Виллем, вы должны запросить файл в такой форме

def create_course(request):
    form = CreateCourseForm()

    if request.method == 'POST':
        form = CreateCourseForm(request.POST, request.FILES)
        if form.is_valid():
            new_course = form.save(commit=False)
            new_course.instructor = request.user
            new_course.save()
            return redirect('home')
    return render(request, 'courses/create.html',{'form':form})

но я думаю, что вы должны знать еще одно, что вам не нужно передавать / при указании django места загрузки файла

class Course(models.Model): 
    name = models.CharField(max_length=200)
    instructor = models.ForeignKey(User, on_delete=models.CASCADE)
    video = models.FileField(upload_to='videos')
    description = models.TextField()
    category = models.ForeignKey(Category, on_delete=models.CASCADE)

    def __str__(self):
        return self.name

Конечно, ответ Виллема решит вашу проблему, но вы увидите, что в вашей папке media создана новая папка с именем videos/, в которой хранится ваш файл, вместо вашей настоящей папки, потому что вы говорите django загрузить этот файл в папку с именем vedios/, и если django не найдет эту папку, он создаст эту папку с таким именем, а затем будет загружать его

Вернуться на верх