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