pythondjangodatabasesqlitedjango-file-upload

Django File Upload Not Working: Files Not Appearing in Media Directory or Database


I am developing a Django application where users can upload files associated with specific topics and submissions. Despite setting up everything according to the Django documentation, the files do not appear in the specified media directory or in the database after upload. I am using Django 5.0.4 and Python 3.10.

Models.py:

class File(models.Model):
    topic = models.ForeignKey(Topic, related_name='files', on_delete=models.CASCADE, null=True)
    submission = models.ForeignKey(Submission, related_name='files', on_delete=models.CASCADE, null=True)
    filename = models.FileField(upload_to='submissions/', null=True)
    upload_date = models.DateTimeField(auto_now_add=True)
    is_accepted = models.BooleanField(default=False)
     
    def __str__(self):
        return f"File: {self.filename.name} for Topic: {self.topic.name}"
    

Forms.py:

class UploadFileForm(ModelForm):
    class Meta:
        model = File
        fields = ('filename',)
  

Views.py:

def upload_file(request, subm_id, topic_id):
    submission = get_object_or_404(Submission, pk=subm_id)
    topic = get_object_or_404(Topic, pk=topic_id)
    form = UploadFileForm()
    context = {'submission':submission, 'topic':topic, 'form': form}
    
    if request.method == 'POST':
        form = UploadFileForm(request.POST, request.FILES)
        
        if form.is_valid(): 
            file_instance = form.save(commit=False)
            file_instance.topic = topic
            file_instance.submission = submission
            file_instance.save()
            messages.success(request, 'File succesfully uploaded')
            return redirect('upload_file', subm_id=submission.id, topic_id=topic.id)
        else:
            print(request.FILES)
            messages.error(request, 'No file was uploaded')
            form = UploadFileForm()
    return render(request, 'users/upload_file.html', context=context)

Settings.py:

MEDIA_URL = '/media/'
MEDIA_ROOT = BASE_DIR / 'media'

Template:

<form method="POST" action="" enctype="multipart/form-data">
            {% csrf_token %}
            <div class="mb-3">
              <label class="form-label" for="{{ form.filename.id_for_label}} "
                >Загрузите файл</label
              >
              {{ form|crispy }}
            </div>
            <input class="btn btn-secondary" type="submit" value="Submit" />
          </form>

What could be causing this issue and how can I resolve it to ensure files are correctly uploaded and saved in Django?


Solution

  • Here is a list of possible cases:

    1. Missing media url

      if settings.DEBUG: urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

    2. If you submitting files, the form should have enctype="multipart/form-data" info about enctype

    3. Try to print out some lines in your view (this is helpful in many cases), just to see if it works fine or where it breaks.

      def upload_file(request, subm_id, topic_id): submission = get_object_or_404(Submission, pk=subm_id) topic = get_object_or_404(Topic, pk=topic_id) form = UploadFileForm() context = {'submission': submission, 'topic': topic, 'form': form}

       if request.method == 'POST':
           print("POST request received.")
           print("Files in request:", request.FILES)
           form = UploadFileForm(request.POST, request.FILES)
      
           if form.is_valid():
               print("Form is valid.")
               file_instance = form.save(commit=False)
               file_instance.topic = topic
               file_instance.submission = submission
               file_instance.save()
               print(f"File instance created and saved: {file_instance}")
               messages.success(request, 'File successfully uploaded')
               return redirect('upload_file', subm_id=submission.id, topic_id=topic.id)
           else:
               print("Form is not valid. Errors:", form.errors)
               messages.error(request, 'No file was uploaded or form was invalid.')
               form = UploadFileForm()
      
       print("Rendering the upload file page.")
       return render(request, 'users/upload_file.html', context=context)