Skip to main content
 首页 » 编程设计

python之在 Django 中上传后如何获取文件绝对路径

2024年10月01日35dyllove98

我想将文件上传到我的数据库,上传后将其导入并最终将数据导出到我的数据库中。我的上传工作正常,但我不确定上传后如何获取文件的绝对路径。我能够打印出文档的名称,但如果上传了相同的文档名称,它会被附加,但如果我调用 form.cleaned_data['document'].name。我该怎么做才能获取绝对文件路径,然后调用函数开始处理该文件?

所以这就是我想要做的:

  • 用户上传 .csv 文件
  • 文件保存在数据库中(带有描述和文件路径。文件路径正确存储在数据库中)
  • 获取刚刚上传的文件的文件位置
  • 开始处理此文件以转换 .csv 数据并存储在数据库中

模型.py

from django.db import models 
 
# Create your models here. 
class Document(models.Model): 
    description = models.CharField(max_length=255, blank=True) 
    document = models.FileField(upload_to='documents/') 
    uploaded_at = models.DateTimeField(auto_now_add=True) 

View .py

from django.shortcuts import render, redirect 
from django.views import View 
# Create your views here. 
 
from .forms import DocumentForm 
from .models import Document    
 
class  FileUpload(View): 
    def post(self, request): 
        form = DocumentForm(request.POST, request.FILES) 
        if form.is_valid(): 
            print() 
            print(form.cleaned_data['document'].name) 
            form.save() 
            return redirect('main_db_model:home') 
        else: 
            return render(request, 'file_upload_form.html', { 
                'form': form 
            }) 
 
    def get(self, request): 
        form = DocumentForm() 
        return render(request, 'file_upload_form.html', { 
            'form': form 
        }) 

表单.py

from django import forms 
from .models import Document 
 
class DocumentForm(forms.ModelForm): 
    class Meta: 
        model = Document 
        fields = ('description', 'document', ) 

file_upload_form.html(模板):

{% extends "base.html" %} 
 
{% block content %} 
  <form method="post" enctype="multipart/form-data"> 
    {% csrf_token %} 
    {{ form.as_p }} 
    <button type="submit">Upload</button> 
  </form> 
      {% if saved %} 
         <strong>Your profile was saved.</strong> 
      {% endif %} 
  This is the form page 
  <p><a href="{% url 'main_db_model:home' %}">Return to home</a></p> 
 
    <p>Uploaded files:</p> 
      <ul> 
        {% for obj in documents %} 
          <li> 
            <a href="{{ obj.document.url }}">{{ obj.document.name }}</a> 
            <small>(Uploaded at: {{ obj.uploaded_at }})</small> 
            {{ obj.document.url }} 
          </li> 
        {% endfor %} 
      </ul> 
{% endblock %} 

请您参考如下方法:

之前,我建议你把这个upload_to='documents/'改成upload_to='documents/%Y/%m/%d',为什么?这可以处理 documents/ 路径中的巨大文档文件。


form.cleaned_data['document'](或 request.FILES['document'])返回 UploadedFile目的。当然 form.cleaned_data['document'].name 应该只返回一个名字。

class  FileUpload(View): 
    def post(self, request): 
        form = DocumentForm(request.POST, request.FILES) 
        if form.is_valid(): 
            # this `initial_obj` if you need to update before it uploaded. 
            # such as `initial_obj.user = request.user` if you has fk to `User`,  
            # if not you can only using `obj = form.save()` 
            initial_obj = form.save(commit=False) 
            initial_obj.save() 
 
            # return path name from `upload_to='documents/'` in your `models.py` + absolute path of file. 
            # eg; `documents/filename.csv` 
            print(initial_obj.document) 
 
            # return `MEDIA_URL` + `upload_to` + absolute path of file. 
            # eg; `/media/documents/filename.csv` 
            print(initial_obj.document.url) 
 
            form.save() 

但是如果你使用 upload_to='documents/%Y/%m/%d',你会得到不同的结果,

print(initial_obj.document)      # `documents/2017/02/29/filename.csv` 
 
print(initial_obj.document.url)  # `/media/documents/2017/02/29/filename.csv`