Reputation: 3160
I've got a model that contains a relative url, something like "abc.html".
I want to display that relative url in an iframe of a view. The urls can be dynamic, they come and go so I don't think I can solve this via static files.
However, I am unable to get it to work, I think it might be my urlconf or something:
Here's my view:
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})
This is basically my view:
<iframe src="{{ url }}" />
But the iframe will always display a 404 because Django tries to resolve the file not the way my app-directory is structured. In my app I've got the assets folder in which most assets live but I am unable to reference it. I think I cannot use collectstatic because those files will change during runtime and I couldn't get it to work as static files either.
Can you please lend me a helping hand? I just started out learning Django and this behaviour puzzles me. I guess it's related to the URLConf.
Maybe there's a way to derive the absolute url from the relative one for the iframe src.
Edit:
Code for the model (it's really that slim 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
Upvotes: 2
Views: 2170
Reputation: 5362
I can see a couple of issues with your approach here so let me point out what I can and see if I can come up with some advice to help you out.
It looks like the asset_path
is pointing at a file on your server that you want to return, and that the files referenced are stored in a directory called asset. If you want to serve a file directly you're going to need to do that separately from Django. When you're developing you can tell django to serve those files directly by making sure they are beneath the url specified by the STATIC_URL
setting in your settings.py. On a production web server you'll want to configure that webserver to handle those urls itself instead of sending them to django.
Because of how files are handled by django, you shouldn't have views configured to respond to urls under the STATIC_URL
directory. So if you have files being served directly from /assets/
you should not have a view configured to respond to /assets/manage/
(for example). In your example and comments it appears that the view is handling:
and that you are asking the browser to combine that with:
../assetrepository/asset1.html
Which produces:
Which is not going to work because instead of serving the file directly, django is trying to find a view that matches that url (and failing).
Here's how I'd recommend setting it up, with some explanation.
Generally when maintaining records of file-like resources in an application like this, the location of the file is made up of (at least) 3 parts:
In my experience, when it's time to scale you're likely going to be changing #1 and #2, but almost never #3. Because this is the case, it's generally a good idea to keep a reference to the file name itself in the database, but keep the other information in a configuration file or be able to retrieve it in some other way at runtime (perhaps from the request object).
consider this approach:
#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/'
Not only should this work fine (so long as you put your asset files in the /static/assets/assetrepository/
directory) but it will save you all kinds of headaches when you need to move the files to a dedicated file server or S3 to reduce the load on your app server.
Let me know if I've misunderstood your issue. Hope this has helped somewhat.
Upvotes: 1
Reputation: 1
If you want to serve static html file (asset1.html in this case), create 'assets' folder under static files directory:
yourproject/yourapp/static/assets/
Add django.contrib.staticfiles into your INSTALLED_APPS directory in settings.py. Change your assets_path entry in db field to represent something like this:
/static/assets/asset1.html
Done. For more info read django documentation on static files.
Upvotes: 0