我有一个包含相对 URL 的模型,例如“abc.html”。
我想在 View 的 iframe 中显示该相对 url。 url 可以是动态的,它们来来去去,所以我认为我无法通过静态文件解决这个问题。
但是,我无法让它工作,我想这可能是我的 urlconf 或其他原因:
这是我的观点:
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 所在的 Assets 文件夹,但我无法引用它。我想我不能使用 collectstatic,因为这些文件会在运行时发生变化,而且我也无法让它作为静态文件工作。
你能帮我一把吗?我刚开始学习 Django,这种行为让我很困惑。我想这与 URLConf 有关。
也许有一种方法可以从 iframe src 的相对 url 中导出绝对 url。
编辑:
模型的代码(真的是那个超薄的atm)
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
请您参考如下方法:
我可以看出您的方法存在一些问题,所以让我指出我能做些什么,看看我是否可以提出一些建议来帮助您解决问题。
看起来 asset_path 指向您服务器上要返回的文件,并且引用的文件存储在名为 asset 的目录中。如果您想直接提供一个文件,您将需要与 Django 分开进行。当你在开发时,你可以告诉 django 直接提供这些文件,方法是确保它们位于 settings.py 中 STATIC_URL 设置指定的 url 之下。在生产 Web 服务器上,您需要配置该 Web 服务器以自行处理这些 URL,而不是将它们发送到 Django。
由于 django 处理文件的方式,您不应将 View 配置为响应 STATIC_URL 目录下的 url。因此,如果您有直接从 /assets/ 提供的文件,则不应将 View 配置为响应 /assets/manage/(例如)。在您的示例和评论中,该 View 似乎正在处理:
并且您要求浏览器将其与:
../assetrepository/asset1.html
产生:
这是行不通的,因为 django 没有直接提供文件,而是试图找到与该 url 匹配的 View (但失败了)。
以下是我建议的设置方式,并附有一些解释。
通常在这样的应用程序中维护文件类资源的记录时,文件的位置由(至少)3 部分组成:
- 文件所在的服务器或主机
- 文件位置的路径
- 文件本身的名称
根据我的经验,当需要扩展时,您可能会更改#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/'
这不仅可以正常工作(只要您将 Assets 文件放在 /static/assets/assetrepository/ 目录中),而且在您需要移动时它会为您省去各种麻烦将文件传输到专用文件服务器或 S3 以减少应用服务器的负载。
如果我误解了您的问题,请告诉我。希望这对您有所帮助。
