Django下载的图片文件未存储在临时文件中

0 投票
2 回答
1303 浏览
提问于 2025-04-18 12:11

我刚开始学习Django,正在做一个项目,用户可以下载各种图片。我想记录一下下载的图片,所以我想把下载的图片文件存放在一个临时文件里。我为此创建了一个模型,下面是这个模型的代码。

 class Photo(models.Model):
    name = models.CharField(max_length = 100)
    photo = models.ImageField(upload_to = 'downloaded', blank=False,null=True)
    description = models.CharField(max_length = 80 , blank = False , null = True)
    user = models.ForeignKey(User)


    def __unicode__(self):
        return '%s %s %s'  %(self.description,self.name)

    def _get_image_url(self):
        return self.photo

还有views.py的代码。

def download(request,image_id):
    filename = get_object_or_404(Photo,pk = image_id)
    filepath = filename.photo.url
    contributor = filename.user
    wrapper = FileWrapper(open(filepath,'rb',))
    content_type = mimetypes.guess_type(filepath)[0]
    response = HttpResponse(wrapper, mimetype='content_type')
    response['Content-Disposition'] = "attachment; filename=%s" % filepath
    if response and not filename.user==request.user:
                    purchased_image=PhotoDownload(name=filename.name,dowloaded_photo=filepath,user = request.user)
                    purchased_image.save()


    return response

根据我给出的模型和视图,每当我下载一张图片时,应该在media目录下创建一个download文件夹,对吧?可是下载任何图片后,media目录下并没有创建download文件夹,但图片却存储在数据库里,并且有一个类似这样的URL……

http://med.finder-lbs.com/admin/photo/photodownload/2/media/media/photos/2_4.jpg

如果你仔细看看这个URL,你会发现图片存储在/media/media/photos,而它应该存储在media/photos。这是为什么呢?我是不是漏掉了什么,或者有没有其他方法可以把下载的文件存放在临时文件夹里?我的其他照片,比如上传的照片,是存放在临时文件里的,但下载的照片却出现了问题。为了方便理解,这里是settings.py的代码。

import os
SETTINGS_DIR = os.path.dirname(__file__)
PROJECT_PATH = os.path.join(SETTINGS_DIR,os.pardir)
PROJECT_PATH = os.path.abspath(PROJECT_PATH)
# Django settings for shutterstock project.



from django.conf.global_settings import TEMPLATE_CONTEXT_PROCESSORS
TEMPLATE_CONTEXT_PROCESSORS += (
    'django.core.context_processors.request',
)





DEBUG = True
TEMPLATE_DEBUG = DEBUG

#for Template path

TEMPLATE_PATH = os.path.join(PROJECT_PATH,'templates')

# Absolute filesystem path to the directory that will hold user-uploaded files.
# Example: "/var/www/example.com/media/"
MEDIA_ROOT = os.path.join(PROJECT_PATH, 'media')
MEDIA_URL = '/media/' #GORKY >> This was media/

# Absolute path to the directory static files should be collected to.
# Don't put anything in this directory yourself; store your static files
# in apps' "static/" subdirectories and in STATICFILES_DIRS.
# Example: "/var/www/example.com/static/"
STATIC_ROOT = ''

STATIC_PATH = os.path.join(PROJECT_PATH,'static')
#STATIC_PATH = os.path.abspath(os.path.join(PROJECT_PATH, 'static'))

# URL prefix for static files.
# Example: "http://example.com/static/", "http://static.example.com/"
STATIC_URL = '/static/'

# Additional locations of static files
STATICFILES_DIRS = (
# Put strings here, like "/home/html/static" or "C:/www/django/static".
# Always use forward slashes, even on Windows.
# Don't forget to use absolute paths, not relative paths.
 STATIC_PATH,
)

ADMINS = (
    # ('Your Name', 'your_email@example.com'),
)

MANAGERS = ADMINS

DATABASES = {
    'default': {
         'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'mysql',  'sqlite3' or 'oracle'.
         'NAME': 'stock',                      # Or path to database file if using sqlite3.
         # The following settings are not used with sqlite3:
         'USER': '',
         'PASSWORD': '',
         'HOST': '',                      # Empty for localhost through domain sockets or '127.0.0.1' for localhost through TCP.
         'PORT': '',                      # Set to empty string for default.
     }
 }


 ALLOWED_HOSTS = []


 TIME_ZONE = 'America/Chicago'


 LANGUAGE_CODE = 'en-us'

 SITE_ID = 1



 USE_I18N = True


 USE_L10N = True


 USE_TZ = True

 # Absolute filesystem path to the directory that will hold user-uploaded files.
 # Example: "/var/www/example.com/media/"


 # URL that handles the media served from MEDIA_ROOT. Make sure to use a
 # trailing slash.
 # Examples: "http://example.com/media/", "http://media.example.com/"


 # Absolute path to the directory static files should be collected to.
 # Don't put anything in this directory yourself; store your static files
 # in apps' "static/" subdirectories and in STATICFILES_DIRS.
 # Example: "/var/www/example.com/static/"


 # URL prefix for static files.


 # Additional locations of static files


 # List of finder classes that know how to find static files in
 # various locations.
 STATICFILES_FINDERS = (
     'django.contrib.staticfiles.finders.FileSystemFinder',
     'django.contrib.staticfiles.finders.AppDirectoriesFinder',
     'django.contrib.staticfiles.finders.DefaultStorageFinder',
 )

 # Make this unique, and don't share it with anybody.
 SECRET_KEY = '3zf@!cs!z(dsf3&6p93jrc6qz)-22n@uyps!5p*wkr3pxemy9e'

 # List of callables that know how to import templates from various sources.
 TEMPLATE_LOADERS = (
     'django.template.loaders.filesystem.Loader',
     'django.template.loaders.app_directories.Loader',
     'django.template.loaders.eggs.Loader',
 )
 TEMPLATE_DIRS = (TEMPLATE_PATH,)

 MIDDLEWARE_CLASSES = (
     'django.middleware.common.CommonMiddleware',
     'django.contrib.sessions.middleware.SessionMiddleware',
     'django.middleware.csrf.CsrfViewMiddleware',
     'django.contrib.auth.middleware.AuthenticationMiddleware',
     'django.contrib.messages.middleware.MessageMiddleware',
     # Uncomment the next line for simple clickjacking protection:
     # 'django.middleware.clickjacking.XFrameOptionsMiddleware',
 )

 ROOT_URLCONF = 'shutterstock.urls'

 # Python dotted path to the WSGI application used by Django's runserver.
 WSGI_APPLICATION = 'shutterstock.wsgi.application'



INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    # Uncomment the next line to enable the admin:
    'django.contrib.admin',
    # Uncomment the next line to enable admin documentation:
    # 'django.contrib.admindocs',

    'photo',
    'userena',
    'guardian',
    'easy_thumbnails',
    'accounts',
    'cloudinary',
    'paypal.standard.ipn',
    'myprofile',
    'watermarker',
    'mail',
    'stored_messages',
    'rest_framework',
    'endless_pagination',
    'home',
    'easy_thumbnails',



  )

 MESSAGE_STORAGE = 'stored_messages.storage.PersistentStorage'

 WATERMARKING_QUALITY = 85
 WATERMARK_OBSCURE_ORIGINAL = False
 WATERMARK_OBSCURE_ORIGINAL = False

 AUTHENTICATION_BACKENDS = (  
    'userena.backends.UserenaAuthenticationBackend',  
    'guardian.backends.ObjectPermissionBackend',  
    'django.contrib.auth.backends.ModelBackend',  
)  

ANONYMOUS_USER_ID = -1

SESSION_SERIALIZER = 'django.contrib.sessions.serializers.JSONSerializer'

AUTH_PROFILE_MODULE = 'accounts.MyProfile'  

LOGIN_REDIRECT_URL = '/accounts/%(username)s/'  
LOGIN_URL = '/accounts/signin/'  
LOGOUT_URL = '/accounts/signout/'  


LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'filters': {
        'require_debug_false': {
            '()': 'django.utils.log.RequireDebugFalse'
        }
    },
    'handlers': {
        'mail_admins': {
        'level': 'ERROR',
        'filters': ['require_debug_false'],
        'class': 'django.utils.log.AdminEmailHandler'
      }
   },
   'loggers': {
        'django.request': {
        'handlers': ['mail_admins'],
        'level': 'ERROR',
        'propagate': True,
        },
   }
}

THUMBNAIL_ALIASES = {
    '': {
       'mini': {'size': (50, 50), 'crop': True},
       'small': {'size': (100, 100), 'crop': True},
       'regular': {'size': (200, 200), 'crop': True},
       'large': {'size': (500, 500), 'crop': True},
       'xl': {'size': (800, 800), 'crop': True},
       'a4': {'size': (800, 600), 'crop': True},
       },
   }

你有什么想法吗?

2 个回答

0

跟踪下载

为了记录图片的下载情况,你需要做一些这样的事情:

models.py:

from django.contrib.auth.models import User

class Photo(models.Model):
    photo = models.ImageField(upload_to = 'downloaded', blank=False,null=True)
    ...

class Download(models.Model):
    photo = models.ForeignKey(Photo)
    user = models.ForeignKey(User, related_name='downloads')
    downloaded = models.DateTimeField(auto_now_add=True)
    # any other fields you want to store

views.py:

def download(request, photo_id):
    photo = get_object_or_404(Photo, pk=photo_id)
    download = Download(photo=photo, user=request.user)
    download.save()
    # serve file

这样做会在数据库中为每次文件下载创建一条记录,记录内容包括下载的文件、下载的用户以及下载的日期和时间。如果没有登录的用户,你可以存储其他信息,比如客户端的IP地址。

显示下载列表

为了给当前用户展示下载列表,你可以使用这样的视图和模板:

views.py:

def my_downloads(request):
    downloads = request.user.downloads.all()
    return render(request, "my_downloads.html", {'downloads': downloads})

my_downloads.html:

...
<p>You've downloaded the following images:</p>
<ul>
    {% for download in downloads %}
        <li>{{ download.photo.photo.name }}</li>
    {% endfor %}
</ul>
...

进一步帮助

关于你现在如何处理# serve file的部分,你可能不想直接在视图中提供文件。你可以简单地将请求重定向到文件的URL:

from django.shortcuts import redirect

def download(request, photo_id):
    ...
    return redirect(photo.photo.url)

这样一来,Django就不需要实际发送文件了。

0

Image的upload_to属性告诉Django在上传文件时应该把文件存储在哪里,而不是下载时。下载文件的时候存储文件是没有意义的……你可不想每次下载同一个文件时,硬盘上都多出一个副本,对吧?

如果你想记录请求的日志,可以把图片的ID或者文件名存储在数据库里。你可以通过创建一个新模型来实现,里面包含时间戳和一些日志信息。

撰写回答