在iframe中显示相对网址
我有一个模型,里面包含一个相对网址,比如“abc.html”。
我想在一个视图的iframe中显示这个相对网址。因为这些网址是动态的,会不断变化,所以我觉得不能通过静态文件来解决这个问题。
但是,我一直没法让它正常工作,我觉得可能是我的网址配置有问题:
这是我的视图:
def detail(request, asset_id):
asset = get_object_or_404(Asset, pk=asset_id)
relative_path = asset.asset_path
return render_to_response('html/detail.html', {'asset': asset, 'url': relative_path})
这基本上就是我的视图:
<iframe src="{{ url }}" />
但是,iframe总是显示404错误,因为Django试图按照我的应用目录结构去查找文件。在我的应用中,有一个assets文件夹,里面存放了大部分资源,但我无法引用它。我觉得我不能使用collectstatic,因为这些文件在运行时会变化,我也没法把它们当作静态文件来使用。
你能帮我一下吗?我刚开始学习Django,这种情况让我很困惑。我想这可能和网址配置有关。
也许有办法从相对网址推导出绝对网址,以便用于iframe的src。
编辑:
模型的代码(现在真的很简单)
class Asset(models.Model):
name = models.CharField(max_length=100)
asset_path = models.CharField(max_length=4096)
creation_date = models.DateTimeField(auto_now=True)
def __unicode__(self):
return self.name
2 个回答
如果你想提供一个静态的 HTML 文件(这里是 asset1.html),首先在静态文件的目录下创建一个叫 'assets' 的文件夹:
yourproject/yourapp/static/assets/
接着,在 settings.py 文件中的 INSTALLED_APPS 列表里添加 django.contrib.staticfiles。然后,把数据库字段中的 assets_path 修改成类似这样的内容:
/static/assets/asset1.html
完成了。想了解更多信息,可以查看 Django 关于静态文件的文档。
我看到你在这里的方法有几个问题,想跟你说说我的看法,并看看能不能给你一些建议。
看起来你提到的 asset_path
是指向你服务器上一个你想返回的文件,而这些文件存放在一个叫做 asset 的文件夹里。如果你想直接提供一个文件,你需要单独处理这个事情,而不是通过 Django。当你在开发时,可以通过确保这些文件在 STATIC_URL
设置指定的 URL 下面,告诉 Django 直接提供这些文件。在生产环境的服务器上,你需要配置这个服务器自己处理这些 URL,而不是把它们交给 Django。
由于 Django 处理文件的方式,你不应该让视图去响应 STATIC_URL
目录下的 URL。所以如果你有文件直接从 /assets/
提供,你就不应该有视图去响应 /assets/manage/
这样的请求(举个例子)。在你的例子和评论中,似乎视图正在处理:
而你又请求浏览器把这个和:
../assetrepository/asset1.html
结合起来,这样就生成了:
这样是行不通的,因为 Django 不是直接提供这个文件,而是在尝试找到一个匹配这个 URL 的视图(结果失败了)。
我建议你这样设置,并给你一些解释。
一般来说,在像这样的应用中维护文件资源的记录时,文件的位置由(至少)三个部分组成:
- 文件所在的服务器或主机
- 文件位置的路径
- 文件本身的名称
根据我的经验,当需要扩展时,你可能会改变第 1 和第 2 部分,但几乎从来不会改变第 3 部分。因为这样,所以通常建议在数据库中保留文件名的引用,而把其他信息放在配置文件中,或者在运行时以其他方式获取(也许从请求对象中)。
考虑一下这种方法:
#models.py
class Asset(models.Model):
name = models.CharField(max_length=100)
asset_filename = models.CharField(max_length=4096)
creation_date = models.DateTimeField(auto_now=True)
def __unicode__(self):
return self.name
#views.py
from urlparse import urljoin
def detail(request, asset_id):
asset = get_object_or_404(Asset, pk=asset_id)
asset_url = build_asset_url(request.get_host(), settings.ASSET_URL, asset.asset_filename)
return render_to_response('html/detail.html', {'asset': asset, 'url': asset_url})
def build_asset_url(host, path, filename):
""" Builds an absolute url to an asset located on the current server """
url = "http://" % host
url = urljoin(url, path)
return urljoin(url, filename)
#settings.py
STATIC_URL = '/static/'
ASSET_URL = '/static/assets/assetrepository/'
只要你把资产文件放在 /static/assets/assetrepository/
目录下,这样应该没问题,而且当你需要把文件移动到专用文件服务器或 S3 上以减轻应用服务器的负担时,这样做会省去很多麻烦。
如果我误解了你的问题,请告诉我。希望这些对你有帮助。