Static files being referenced via different path in same Django view - django

I recently updated one of my views and URLs to take an additional parameter and now that I have done this the page which is rendered displays with no css or javascript because the static path is wrong.
I am obviously not understanding correctly how static is served however I didn't think that changing the URL confs would change the path that Django would look for static. All my static for the whole site is in the one place.
urls.py
url(r'^fill/(.*)/(.*)/$', views.fill_survey, name='unique_getfile'),
url(r'^fill/(.*)', views.fill_survey, name='unique_getfile'),
and here is my view ... first block executes for the first url match and the second block executes for the bottom url
def fill_survey(request, unique_url, new_name="blank"):
"""
get file or redirect to error page
"""
if len(unique_url) < 50:
if unique_url == "new":
firstlast = new_name.split(" ")
c = Client.objects.get(firstname=firstlast[0], lastname=firstlast[1])
survey_url_number = generate_survey(request, c.email)
response = Survey.objects.get(number=survey_url_number['number'])
return render(request, 'survey/survey.html', {'survey': response})
else:
response = Survey.objects.get(number=unique_url)
return render(request, 'survey/survey.html', {'survey': response})
The rendered page then has the following static paths for the first and second url match respectively:
wwww.mysite.com/static/etc...
www.mysite.com/module_name/static/etc...
Paths in my template like:
<link rel="stylesheet" href="../../../static/classic/global/css/bootstrap.min.css">
Why are these different URLs leading to different static paths?
Thanks in advance!

Here's the relevant docs but by default Django only looks for static resources in /static/ folder or its subfolders. You can define a list of static file directories in your settings file if you want though.
https://docs.djangoproject.com/en/2.0/howto/static-files/
EDIT: Response to comment.
Can I see your template? Also, I'd try changing all your urls to end in a /$.
EDIT: Response to posted template.
I use the static tag rather than the absolute. I.E.
<link rel="stylesheet" href="{% static "/css/bootstrap-3.3.7.min.css" %}">
This way if we mess with the location of our templates we don't ned to go back and change all the templates
.
A couple thought about your html:
Since it doesn't start with / it's pointing to the a folder within the current folder.
With a / it points to the path at the root of your current web.
See https://www.w3schools.com/html/html_filepaths.asp
Regarding why I end my addresses in /$. Here's a good answer.
Why django urls end with a slash?
I wish I had a clearer answer for you but try the trailing / in the url and the leading / or {% static %} in your template.

Related

Django: path to static file is wrong in generated HTML

I have some javascript that I would like to run on a particular page of a Django site I am building. In the template I currently have:
<script type='text/javascript' src='{% static "/home_page/github_repos.js" %}'></script>
The HTML that is generated by this is:
http://localhost:8000/home_page/github_repos.js
The problem is that I have the javascript in /static/home_page/.
If I hardcode in the path as:
<script type='text/javascript' src='static/home_page/github_repos.js'></script>
Everything works fine.
However, I am getting odd behavior that I do not understand:
If, in the template I set the path like this:
<script type='text/javascript' src='{% static "static/home_page/github_repos.js" %}'></script>
The HTML generate has a src attribute of /static/static/home_page/github_repos.js
The part that is really throwing me off is that if I do not put /static/ at the front of the src when using the template tags (like the first example I give), /static/ is not added, however, if I do add /static/ at the front, it gets added. I need /static/ added to the front of the src attribute, but only once.
Some relevant information:
My home_page app resolves to '/' as the url, so localhost:8000/ gets you to the home page.
I have included'django.contrib.staticfiles' in my installed apps
Finally, STATIC_URL = '/static/'
Is this problem occurring because my home_page app resolves to the root address of localhost:8000/?
Any help is appreciated.
This issue is because the path in the static tag should be relative to the static directory. From the docs:
Uses the configured STATICFILES_STORAGE storage to create the full URL for the given relative path
You're using an absolute path. Instead, you should use:
{% static "home_page/github_repos.js" %}
Note the omission of the leading forward slash.

Is it possible to hardcode CSS link in django?

I have an django project and want to hardcode a link to CSS (I do not want to use STATIC_FILES...etc). The reason is because I want to be able to click index.html and it will work on browser (including getting the css file).
I put both index.html and index.css in the same directory and added this line in index.html:
<link rel="stylesheet" type="text/css" href="./index.css"/>
When I double-click index.html, it imports index.css perfectly.
However, when I load it with the django development server and open via browser, it does not import the index.css.
What should be done so that index.html takes the index.css?
The answer by Christopher Schäpers works nicely, I'd like to extend her answer by showing how you may actually do what she suggests.
Let's say you have
<link rel="stylesheet" type="text/css" href="/index.css"/>
which means the browser is requesting to localhost:8000/index.css, so in your root urls.py file, you add something like this
from django.urls import path
from django.conf import settings
from django.http import HttpResponse
def css_path(request): # This is basically a "view"
path = settings.BASE_DIR / 'index.css' # For earlier Django version: os.path.join(settings.BASE_DIR, 'index.css')
with open(path, 'rb') as f:
content = f.read()
return HttpResponse(content, content_type='text/css')
urlpatterns = [
# ... (your other url patterns)
path('index.css', css_path)
]
NOTE: Remember to set the content_type keyword argument correctly base on what you are serving (Example: application/javascript for .js, image/png for .png, .etc).
That's because the browser uses a directory based approach.
Say your template directory looks like this:
/home/yura/project/templates/
→ index.html
→ index.css
When opening index.html with your browser it plainly looks for index.css in the same directory, thus for /home/yura/project/templates/index.css.
Now when you run the development server it's not directory based anymore. There's the urls.py file that specifies where each path leads to.
You probably have a route / that leads to index.html even though index.html isn't called nothing. You could also add a route /blog/ that may lead to blog_home.html even though the file is called blog_home.html.
Every url that enters django is routed through the urls.py file.
This is one of django's core concepts. URLs should be user-typable and readable without cruft as .php, .html and so on that comes from directory based approaches like PHP or CGI.
Since you haven't defined a route called /index.css thus index.css isn't found.
If the thing you are doing is a one-off your best bet would be to just add a route to /index.css that delivers index.css.
Otherwise there is no way of doing this, since django isn't directory based, as pointed out above.
You might then want to think about why exactly you want to be able to open the raw html file directly in the browser too, since it makes the django templating language entirely useless for you, thus you can't do anything variable, loop and logic related and are stuck with basic html where you, instead of the django-dev server could just as well use a simple http-server instead.

Django CSS & Static Media Not Loading

So I've been hitting my head against the wall on this for the last hour and can't seem to figure out why none of the static media (CSS, Images, JS etc) when my template is rendered.
Could someone please help me find out why adjustments I need to make? Below are snippets from Settings.py, Index.html and stylesheet please let me know if more is needed.
My static files are located in the following directory:
/djangoproject/website/static
Settings.py - Located /djangoproject/djangoprojectname/
STATIC_ROOT = os.path.normpath(os.path.join(PROJECT_ROOT,
"/static/"))
STATIC_URL = '../website/static/'
Here's a snippet from my index.html that is supposed to be calling the css style sheet with {{ STATIC_URL }}
Index.html - Location /djangoproject/website/templates/
<link rel="stylesheet" href="{{ STATIC_URL }}css/style.css">
Location of CSS StyleSheet
style.css - Location /djangoproject/website/static/css/
From the Django docs:
If {{ STATIC_URL }} isn't working in your template, you're probably
not using RequestContext when rendering the template.
As a brief refresher, context processors add variables into the
contexts of every template. However, context processors require that
you use RequestContext when rendering templates. This happens
automatically if you're using a generic view, but in views written by
hand you'll need to explicitly use RequestContext To see how that
works, and to read more details, check out Subclassing Context:RequestContext.
It seems to me that you are setting STATIC_URL to a path, when it should be set to, well, a URL. You need to set this to the web address of the folder that contains your css files, for example:
STATIC_URL = 'http://mydomain.com/static_files/'
Try to find your CSS file online by typing the address you expect it to be into your browser. Once you find the CSS file this way, just copy the root URL that got you there.

How to render a template with dynamic CSS?

I want to create a dynamic CSS file in a view and then render a template which loads that CSS file. Depending on the arguments given to the view, the CSS may have different values at certain places every time the view is called. How would I go about doing that? (I should add that I have no experience with writing files in Python/Django.)
Here is a simplified example of how I think it should work:
# urls.py
urlpatterns = patterns('',
(r'^myview/(?P<color>[0-9a-f]{6})/$', create_css_file),
)
# views.py
def create_css_file(request, color):
raw = "#charset 'UTF-8';\n\n"
raw += "body {\n"
raw += " color: #" + color + ";\n"
raw += "}\n\n"
f = open('mydynamic.css', 'r+')
f.write(raw)
return render_to_response('mytemplate.html', locals())
# mytemplate.html
{% extends "base.html" %}
{% block head %}
<link rel="stylesheet" media="screen" href="{{ f.name }}" />
{% endblock %}
For some reason, that doesn't work, although in the resulting HTML page's source code, it looks like the CSS file is loaded correctly. The f even arrives at the template correctly, because I can see its contents when I change the <link>... line to
<link rel="stylesheet" media="screen" href="{{ f }}" />
(finstead of f.name). But the HTML is rendered without the desired color setting. Can anybody tell my why that is?
I suspected some path issue, and I toyed around quite a bit with different paths, but to no avail.
Please do not advise me to prepare several hardcoded CSS files (as I have found in answers to similar questions), because there will be several hundred possibilities.
If you absolutely need to you can just create a css file dynamically.
You can create an entry in your urls.py. You can name urls anything you want this could look like a static .css file to the outside world but would be created dynamically.
(r'^(?P<color>[0-9a-f]{6})/dynamic.css$', dynamic_css)
def dynamic_css(request, color):
"""
Create a css file based on a color criteria,
or any other complicated calculations necessary
"""
# do custom element positionting.
return render_to_response('dynamic.css', {'color': color})
# dynamic.css
body {
background-color: {{ color }}
}
There is no reason to write css files for this. Now you can just include
<link rel="styleshee" type="text/css" href="/purple/dymamic.css" />
In your template.
As mentioned this shouldn't be used just for changing one color. That could be done in your template. If you had to do something like this it would probably be a good idea to implement cacheing as every time a page is requested it has to dynamically generate .css that could be performance overhead. This is more of an example to show you can name urls.py entries anything you want. And include them in any way you want in html ie. if you needed a custom javascript file dynamically created you could create an entry in urls.py and then create a view that generates a .js file.
views.py:
def create_css_file(request, color):
f = color
return render_to_response('mytemplate.html', locals())
template:
<body style = "color:{{f}}!important;">
Don't create css file on the fly it is unnecessary.
I went with #CatPlusPlus's suggestion: Calculating the necessary values in a view and passing the template a very long string (raw) which contains the entire CSS. In the template, I include it like so:
<style media="screen">{{ raw|safe }}</style>
Thanks everyone for your efforts!

Django: Error 500 for favicon

On my local server, I'm getting the following error in terminal
[03/Oct/2011 22:49:19] "GET /favicon.ico/ HTTP/1.1" 500 65893
In my site_base.html, I already have the following line:
<link rel="icon" href="{{ STATIC_URL }}images/favicon.ico" />
What's causing this error and how can I make it stop?
The default lookup browsers do is /favicon.ico. However, since you specified the link the browser shouldn't be doing this. There's most likely a bug in the particular browser and version you're using responsible for sending the extra request, but that's beside the point.
You're getting a 500 error because that particular request is making it into the Django URL handling machinery, and whatever view is responding to, is choking on the provided arguments.
Check your urls.py and see which pattern(s) will accept the URL /favicon.ico/. Then, go into the corresponding views and see why it's causing it to choke, or alter the pattern such that it won't catch a URL like this, as it mostly likely shouldn't be in the first place.
This may not be 100% the issue that you're facing, but it's worth mentioning since you're using a custom favicon stored in your static folder.
In Django templating, you can manage your static assets like this:
{% load static %}
<link rel="shortcut icon" href="{% static 'img/favicon.ico' %}">
No need to send a {{ STATIC_URL }} context variable into the template.
In my case, the problem was appearing when I was trying to log in on the admin panel.
My error was:
ValueError: unsupported format character 'C' (0x43) at index 34
Internal Server Error: /favicon.ico
The problem was nested in my urls.py:
Suggestions from other users help me a little but in the end, the documentation was a game changer. Quote:
from django.contrib.staticfiles.storage import staticfiles_storage # for `favicon` -> https://simpleit.rocks/python/django/django-favicon-adding/
from . import views
urlpatterns = [
path('favicon.ico', RedirectView.as_view(url=staticfiles_storage.url('project_foo\logos\media\favicon.ico')))]
I mean line: path('favicon.ico', RedirectView.as_view(url=staticfiles_storage.url('project_foo\logos\media\favicon.ico')))]
As the documentation stated quote: django.contrib.staticfiles collects static files from each of your applications (and any other places you specify) into a single location that can easily be served in production.
In my case, I pointed out a file, not the location. Things were ok on the user page, but throw an error on the admin panel.
The solution in my case is:
`path('favicon.ico', RedirectView.as_view(url=staticfiles_storage.url('project_foo\logos\media')))]`