Python Django导入自定义存储时遇到的问题及解决方案

70 阅读1分钟

一名开发者正在使用 Django 框架开发一个应用程序,并在其中设计了一个名为 FTPStorage 的自定义存储系统。在 models.py 文件中,他导入了 FTPStorage 并将其用于 FileField 存储,然后在 views.py 中也导入了 FTPStorage 以便使用它来上传文件。但是,当他尝试运行应用程序时,出现了错误信息:“Could not import app.views. Error was: cannot import name FTPStorage”。

huake_00152_.jpg

2、解决方案

为了解决这个问题,开发者需要将 FTPStorage 模块添加到 Python 的搜索路径中。可以通过在 Apache 的配置中设置 PythonPath 来完成。配置如下:

PythonPath "sys.path+['/mydir']"

其中 /mydir 是 FTPStorage 模块所在目录的完整路径。添加了这一配置后,Python 将能够找到 FTPStorage 模块,应用程序将能够正常运行。

代码例子

models.py 文件:

from FTPStorage import FTPStorage
import datetime
from django.db import models

fs = FTPStorage()

class Upload(models.Model):
    file = models.FileField(upload_to='uploads', store=fs)
    timestamp = models.DateTimeField(default=datetime.datetime.now)
    notes = models.CharField(max_length=255, blank=True)

    class Meta:
        ordering = ['-timestamp',]

    def __unicode__(self):
        return u"%s" % (self.file)

    @property
    def size(self):
        return filesizeformat(self.file.size)

views.py 文件:

from forms import UploadForm
from models import Upload
import ftplib
import os
import datetime
from django.forms import save_instance
from django.shortcuts import render_to_response
from django.template import RequestContext
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
from django.http import HttpResponse
from FTPStorage import FTPStorage
from django.core.files.storage import Storage

def initial(request):
    data = {

        'form': UploadForm(),
    }
    return render_to_response('upload.html', data, RequestContext(request))


def upload(request):
    if request.method == 'POST':
        form = UploadForm(request.POST, request.FILES)
        if form.is_valid():
            upload = Upload()
            upload.timestamp = datetime.datetime.now()
            save_instance(form, upload)
            return HttpResponseRedirect(reverse('initial'))

FTPStorage.py 文件:

import ftplib
import os
from django.core.files.storage import Storage

class FTPStorage(Storage):
    def __init__(self, location=None, base_url=None):
        self.location = location
        self.base_url = base_url

    def _open(self, name, mode='rb'):
        ftp = ftplib.FTP(self.location)
        ftp.login()
        ftp.cwd('uploads')
        return ftp.retrfile(name)

    def _save(self, name, content):
        with ftplib.FTP(self.location) as ftp:
            ftp.login()
            ftp.cwd('uploads')
            ftp.storbinary('STOR %s' % name, content)
        return name

    def exists(self, name):
        ftp = ftplib.FTP(self.location)
        ftp.login()
        ftp.cwd('uploads')
        try:
            ftp.retrbinary('RETR %s' % name, open(os.devnull, 'wb').write)
            return True
        except ftplib.error_perm:
            return False

    def url(self, name):
        if self.base_url is None:
            raise ValueError("This file has no URL.")
        return '%s/%s' % (self.base_url, name)

    def delete(self, name):
        ftp = ftplib.FTP(self.location)
        ftp.login()
        ftp.cwd('uploads')
        ftp.delete(name)