Is it possible to hardcode CSS link in django? - 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.

Related

Changing URL pattern in Django so it doesn't show app name

I've got a folder/app named "projects" and there I want to make a new site there, named, let's say, "cheese".
In my urlpatterns in urls.py in projects folder I've got
path('cheese/', views.cheese, name='cheese')
but the whole URL looks like domain.co/projects/cheese
I'd like to omit that projects in URL, so it could just be domain.co/cheese
Those URL-things are kinda hard to understand for me and as I couldn't properly name my problem, I couldn't find a solution out there, though I believe there must be some.
The idea of having an app inside another app is kinda weird, but anyways, that won't enforce the inner app's urls to be like <outer_app>/<inner_app>/... if you set the url patterns correctly.
Basically, you've got domain.co/projects/cheese because, you include your project's app urls as:
# main urls.py file for your project
path('projects/', include('projects.urls'))
and in your project's urls file you have:
# projects/urls.py
path('cheese/', include('projects.cheese.urls'))
So if you want to have the cheese urls as domain.co/cheese, simply add the include to the main url file:
# main urls.py file for your project
path('projects/', include('projects.urls'))
path('cheese/', include('projects.cheese.urls'))

Static files being referenced via different path in same Django view

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.

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.

Getting Page not found (404) in Django 1.3.1 from bad url pattern

I am following along with this Django blog tutorial and can not get the url pattern given in the tutorial to work properly. The url.py code the author gives is
(r'^static/(?P
.*)$', 'django.views.static.serve',
{'document_root': 'c:/static/adornment'}),)
and I adapted it to my Linux set up like this
from django.conf.urls.defaults import patterns, include, url
urlpatterns = patterns('',
(r'^static/(.*)$', 'django.views.static.serve',
{'document_root': '/home/sez/blog/static/image.png'}
),
)
and after going to http://127.0.0.1:8000/static/image.png I received the following error
Page not found (404)
Request Method: GET
Request URL: http://127.0.0.1:8000/static/image.png
'image.png' could not be found
How can I make this work?
Change up your 'document_root' to be a directory, and make sure your STATIC_URL setting is set to /static/
The likely reason for the behavior you were experiencing is as follows. You probably have 'django.contrib.staticfiles' included in your INSTALLED_APS in the "settings.py" file. In that case, when you run "manage.py runserver" (and you have DEBUG = True in your "settings.py"), static files will be automatically served from your STATIC_URL by the staticfiles app and not by your 'django.views.static.serve' URL pattern. However, in your case staticfiles app is not set up correctly and won't find your 'image.png' file. You might want to read more about conventional serving of static files here: Managing static files.
For that matter, STATIC_URL is not supposed to be a filesystem path like you have now: STATIC_URL.
When you made it that way, you effectively disabled staticfiles app and your code started working as a result :)
So, to solve your problem "correctly", you need to either make sure that STATIC_URL and the URL path in your "urls.py" are different, for example, make one of them "/static/" and another one "/media/" (or something else), or just remove "django.contrib.staticfiles" from your INSTALLED_APPS altogether if you don't use it. (And, of course, the advice about making 'document_root' a directory was entirely correct. You can read more about using 'django.views.static.serve' here: Serving static files in development.)

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')))]`