使用django或任何python模块的链接生成器
问题出现的原因:
用户建议使用某种动态url配置。但是可能存在一些担忧,为什么不通过简化设置一个仅捕获依赖于用户/时间的大型编码字符串的单个url来忘记这些担忧呢?
解决方法:
可以使用以下代码实现:
(r'^download/(?P(.*)/$', 'download_file'), # use your own regexp def download_file(request, encrypted_id): decrypted = decrypt(encrypted_id) _file = get_file(decrypted) return _file
许多网站也只是使用一个get参数。
www.example.com/download_file/?09248903483o8a908423028a0df8032
如果你担心性能问题,可以查看这个帖子中的答案:Having Django serve downloadable files。其中强调了使用Apache x-sendfile模块的方法。
另一种选择是简单地重定向到由Django提供的静态文件。
问题:如何使用Django或任何Python模块生成链接?
原因:一般情况下,我们不希望Django处理文件的服务,因此不应该使用url patterns。相反,我们希望能够生成一个随机的密钥来作为链接,并将文件和密钥存储在数据库中。为了实现这个目标,我们需要创建一个下载目录,并增加一个定时任务来检查链接的有效期并清理文件和数据库条目。
解决方法:首先,我们可以使用哈希算法(如md5或sha1)生成一个随机的密钥。然后,我们将文件复制到一个可从web服务器(如Apache或Nginx)访问的根目录中。为了保证链接的有效期,我们可以创建一个定时任务,在链接生成后一段时间后检查链接的有效性,并清理文件和数据库条目。在Django的`manage.py`中可以编写一个命令来实现这个功能。
如果还希望链接受到密码保护,可以考虑使用httpbasic auth。可以在创建链接或注册时使用`htpasswd`和`subprocess`模块动态生成和删除httpd.auth文件中的条目。
下面是一个示例代码,仅供参考,还未测试。代码中包括了一个用于存储链接信息的模型,以及生成链接和检查链接有效期的函数。
import hashlib, random, datetime, os, shutil # 用于存储链接信息的模型,包括字段:key (charfield), filepath (filepathfield), datetime (datetimefield), url (charfield), orgpath (filepathfield)或原始路径的foreignkey from models import MyDlLink # 应用程序的settings.py from myapp import settings as myapp_settings # 要下载的文件的完整路径和名称 def genUrl(filepath): # 创建一个随机的salt来增加链接的随机性 salt = ''.join(['{0}'.format(random.randrange(10) for i in range(10)]) key = hashlib('{0}{1}'.format(salt, filepath).hexdigest() newpath = os.path.join(myapp_settings.DL_ROOT, key) shutil.copy2(fname, newpath) newlink = MyDlink() newlink.key = key newlink.date = datetime.datetime.now() newlink.orgpath = filepath newlink.newpath = newpath newlink.url = "{0}/{1}/{2}".format(myapp_settings.DL_URL, key, os.path.basename(fname)) newlink.save() return newlink # 用于检查链接是否过期的命令 def check_url_expired(): maxage = datetime.timedelta(days=7) now = datetime.datetime.now() for link in MyDlink.objects.all(): if(now - link.date) > maxage: os.path.remove(link.newpath) link.delete()
参考链接:[1] http://docs.djangoproject.com/en/1.2/howto/static-files/
问题出现的原因是需要一个链接生成器,可以使用Django或任何Python模块来实现。解决方法如下:
首先,我们可以使用用户名和时间戳的哈希摘要作为简单的方案。代码如下所示:
from datetime import datetime from hashlib import sha1 user = 'bob' time = datetime.now().isoformat() plain = user + '\0' + time token = sha1(plain) print token.hexdigest() # 输出:1e2c5078bd0de12a79d1a49255a9bff9737aa4a4
接下来,将生成的token存储在一个带有过期时间的memcache中。这样,任何一个web服务器都可以访问它,并且token会自动过期。代码如下所示:
import memcache # 连接到memcache服务器 mc = memcache.Client(['127.0.0.1:11211']) # 存储token,并设置过期时间为3600秒(1小时) mc.set('token', token.hexdigest(), time=3600)
最后,在Django中添加一个URL处理程序,用于处理以'^download/.+'开头的URL。在处理程序中,可以通过在memcache中查找该token来确定token是否有效。甚至可以将要下载的文件名存储为memcache中的token的值。代码如下所示:
from django.http import HttpResponseNotFound, HttpResponse def download_file(request, token): # 从memcache中查找token file_name = mc.get(token) if file_name is None: # 如果token不存在,则返回404错误 return HttpResponseNotFound() # 下载文件的代码逻辑 file_path = '/path/to/files/' + file_name with open(file_path, 'rb') as file: response = HttpResponse(file.read(), content_type='application/octet-stream') response['Content-Disposition'] = 'attachment; filename="' + file_name + '"' return response
以上就是使用Django或任何Python模块来创建链接生成器的解决方法。通过使用哈希摘要生成token,并将其存储在memcache中,可以实现自动生成和自动过期的链接。同时,通过在Django中添加URL处理程序,可以验证token的有效性并下载相应的文件。