使用django或任何python模块链接生成器

时间:2011-03-16 03:27:47

标签: python django

我想为我的用户生成临时下载链接。 如果我使用django使用url模式生成链接,那可以吗? 这可能是正确的方法。因为可能发生我不理解某些过程如何工作。它会溢出我的记忆或其他东西。将会欣赏某种示例或工具。有些nginx,apache模块可能吗?

所以,我想要实现的是制作依赖于用户和时间的网址模式。在文档中查看结束返回。

3 个答案:

答案 0 :(得分:4)

一个简单的方案可能是使用用户名和时间戳的哈希摘要:

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"

接下来,将该令牌存储在具有过期时间的内存缓存中。这样,您的任何网络服务器都可以访问它,令牌将自动过期。最后为'^ download /.+'添加一个Django url处理程序,其中控制器只在memcache中查找该令牌以确定令牌是否有效。您甚至可以将要下载的文件名存储为memcache中的标记值。

答案 1 :(得分:2)

是的,允许django生成网址是可以的。这与urls.py处理网址是排他的。通常你不希望django处理文件的服务,请参阅关于此的静态文件docs [1],因此请从头脑中获取使用url模式的概念。

您可能想要做的是使用哈希生成随机密钥,例如md5 / sha1。存储文件和密钥,它在数据库中添加的日期时间,在您的网络服务器上可以创建下载目录,如apache或nginx ...建议nginx),因为它是临时的,你需要添加一个cron检查自生成url以来的时间是否已过期的作业,清除文件并删除db条目。这应该是manage.py

的django命令

请注意这是为此编写的示例代码,未经测试!它可能无法按照您计划实现此目标的方式运行,但它可行。如果你想让dl受到pw保护,那么请查看httpbasic auth。您可以在创建链接时或在注册时使用htpasswd和子进程模块在httpd.auth文件中动态生成和删除条目。

import hashlib, random, datetime, os, shutil
# model to hold link info. has these fields: key (charfield), filepath (filepathfield)
# datetime (datetimefield), url (charfield), orgpath (filepathfield of the orignal path
# or a foreignkey to the files model.
from models import MyDlLink 
# settings.py for the app
from myapp import settings as myapp_settings

# full path and name of file to dl.
def genUrl(filepath):
  # create a onetime salt for randomness
  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


# in commands
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/

答案 2 :(得分:1)

听起来你建议使用某种动态网址。

为什么不通过简化和设置一个捕获依赖于用户/时间的大型编码字符串的网址来忘记您的顾虑?

(r'^download/(?P<encrypted_id>(.*)/$', 'download_file'), # use your own regexp


def download_file(request, encrypted_id):
    decrypted = decrypt(encrypted_id)
    _file = get_file(decrypted)
    return _file

许多网站也使用了get param。

www.example.com/download_file/?09248903483o8a908423028a0df8032

如果您担心效果,请查看以下帖子中的答案:Having Django serve downloadable files

突出显示apache x-sendfile模块的使用。


另一种选择是简单地重定向到django提供的静态文件。