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

Duc*_*e88 8 python django django-models django-forms django-views

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

所以这就是我想要做的:

  • 用户上传 .csv 文件
  • 文件保存在 db 中(带有描述和文件路径。文件路径正确存储在 db 中)
  • 获取刚刚上传的文件的文件位置
  • 开始处理此文件以转换 .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)
Run Code Online (Sandbox Code Playgroud)

视图.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
        })
Run Code Online (Sandbox Code Playgroud)

表格.py

from django import forms
from .models import Document

class DocumentForm(forms.ModelForm):
    class Meta:
        model = Document
        fields = ('description', 'document', )
Run Code Online (Sandbox Code Playgroud)

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 %}
Run Code Online (Sandbox Code Playgroud)

bin*_*npy 7

以前,我建议你改变这种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()
Run Code Online (Sandbox Code Playgroud)

但是如果你使用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`
Run Code Online (Sandbox Code Playgroud)