I know there have been many questions here on accessing static files in a Django project, but I could not find a satisfactory answer to a problem I am dealing with. So, here's my project structure:
.
├── project
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ ├── wsgi.py
├── db.sqlite3
├── manage.py
└── app
├── admin.py
├── __init__.py
├── migrations
│ ├── __init__.py
├── models.py
├── static
│ └── app
│ └── file.txt
├── tests.py
├── urls.py
└── views.py
As per Django 1.7 documentation I have stored the static file file.txt in app/static/app folder. Now, how do I reference this file in a view? Lets just say I need to read the contents of this file for every call defined in app/views.py.
As usual, I have default setting of STATIC_URL = '/static/' in project/settings.py
Thanks
You can import the static template tag into your view and use it as such:
from django.templatetags.static import static
url = static('app/file.jpg')
You can do this by defining STATIC_ROOT in your settings. Then before running your project you can run
python manage.py collectstatic
And the static files then can be accessed using:-
file = open(os.path.join(settings.STATIC_ROOT, 'app/a.txt'))
This is basically the way, it is supposed to be done in a production environment, as static files are hosted separately from the django html views.
To load the name of app dynamically in project/urls.py
url(r'^', include('app.urls', app_name="app")),
and then in views:-
from django.core.urlresolvers import resolve
def appname(request):
return resolve(request.path).app_name
Related
I am trying to make a Django model of a game with fields for a name and also a cover image that is located in the static folder of the app.
def game_covers_path():
return os.path.join(settings.STATIC_URL, 'some_app/games/')
class Game(models.Model):
name = models.CharField(max_length=100, primary_key=True)
cover = models.FilePathField(path=game_covers_path, null=True)
def __str__(self):
return self.name
My folder structure is as follows:
.
├── db.sqlite3
├── my_app
│ ├── __init__.py
│ ├── asgi.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── manage.py
└── some_app
├── __init__.py
├── admin.py
├── apps.py
├── migrations
├── models.py
├── static
│ └── some_app
│ ├── games
│ │ ├── Counterstrike:\ Global\ Offensive.jpg
├── templates
├── tests.py
├── urls.py
└── views.py
But when I open the admin page I get the following error:
FileNotFoundError at /admin/some_app/game/add/
[Errno 2] No such file or directory: '/static/some_app/games/'
How can I correctly reference images in the static folder of an app in the database? Also does the FilePathField check if the a file exists before saving a model? Because I tried adding random values and it saved it, but in the documentation its written that you can only choose a file that already exists...
(too long for comment)
STATIC_URL is an URL which will be mapped to STATIC_ROOT path by Django in runtime, so use STATIC_ROOT to build file path
static files are not supposed to be dynamically modified: css, js, favicon; what you are trying to do is called media files in terms of Django so use to MEDIA_URL, MEDIA_ROOT instead. Also note, whereas static files are fine to be stored in project folder, media files are usually stored somewhere else. They are not part of your project/solution - they are data.
To handle properly both static and media files you must configure STATIC_ROOT, STATIC_URL, MEDIA_ROOT, MEDIA_URL
There are dozens of questions and answers related to Django static and media files here on SO, please have a look at them. And please take a look at the docs.
I am trying to add a css file to my django application which I am deploying on openshift. Currently, I am able to have the css file work when running locally with debug and all that. However, when I deploy my application to openshift, the css file does not have any effect. Many of the other questions online seem to be referring to old versions of django and openshift (lots of references to a wsgi folder that doesn't seem to be standard anymore and triggering collectstatic manually)
My understanding with the current django/openshift relationship is that I do not need to do collecstatic manually as I am using the django-ex template from openshift, and during the build process the collectstatic command is run automatically, the ouput of which I can see in the logs. Notably, I can see that my style.css file for my application gets copied into STATIC_ROOT in that log.
My project structure from my project root is thus:
.
├── db.sqlite3
├── djangoWrapper
│ ├── __init__.py
│ ├── settings.py
│ ├── templates
│ │ └── djangoWrapper
│ │ └── index.html
│ ├── urls.py
│ ├── views.py
│ └── wsgi.py
├── gitlab-ci.yml
├── ldap
│ ├── admin.py
│ ├── apps.py
│ ├── forms.py
│ ├── __init__.py
│ ├── migrations
│ ├── models.py
│ ├── static
│ │ └── ldap
│ │ └── style.css
│ ├── templates
│ │ └── ldap
│ │ ├── apiOffline.html
│ │ ├── index.html
│ │ ├── results.html
│ │ └── search.html
│ ├── tests.py
│ ├── urls.py
│ └── views.py
├── manage.py
├── openshift
├── README.md
├── requirements.txt
Here's what I am doing in my settings.py:
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
STATIC_URL = '/static/'
STATICFILES_DIRS = [os.path.join(BASE_DIR, "ldap", "static"),]
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
In my html files, I am then trying to load the css file with
{% load static %}
<link rel="stylesheet" type="text/css" href="{% static 'ldap/style.css' %}">
in the <head> section.
I have attempted to do some debugging here because it would be assumed that the problem before I got to deployment was that my static files were not being put in the correct place/djgano couldn't find them. So I put some prints into my app and deployed it on openshift and got back the following info:
BASE_DIR: /opt/app-root/src
STATIC_ROOT: /opt/app-root/src/static
STATIC_URL: /static/
APP_VIEW_DIR: /opt/app-root/src/ldap/views.py
as well putting <p>"{%static 'ldap/style.css' %}"</p> into an html file, which displays as /static/ldap/style.css
From these tidbits, I know that the root directory for openshift is /opt/app-root/src/, that my static files are in /opt/app-root/src/static, and that my html is looking for the css file in /static/ldap/style.css. This seems like it should be working then as all of those directories line up. Is there something else about serving static files with django/openshift that I am missing here?
Finally got it working! I did use whitenoise, following the steps here.
Here is my project folder structure.
<pre>
front
├── __init__.py
├── __init__.pyc
├── manage.py
├── middleware.py
├── settings.py
├── news
│ ├── __init__.py
│ ├── __init__.pyc
│ ├── admin.py
│ ├── admin_views.py
│ ├── models.py
│ ├── search_indexes.py
│ ├── search_sites.py
│ ├── utils.py
│ ├── views.py
</pre>
After I run
./manage.py runserver
then I visit http://127.0.0.1:8000/
It gives me error:
No module named front
This is caused by the following line in file views.py under news folder.
from front import settings
So the front folder is one level up to the views.py file. How I import the settings from one level up folder?
Thanks!
Either way this is wrong, whenever you're importing your own settings you should be importing from django.conf
from django.conf import settings
This isn't a module, its an object that does magic to import any settings you have set in your DJANGO_SETTINGS_MODULE
From the docs:
Also note that your code should not import from either global_settings or your own settings file. django.conf.settings abstracts the concepts of default settings and site-specific settings; it presents a single interface. It also decouples the code that uses settings from the location of your settings.
What is the most reusable way for the "extends" method in django templates?
I have seen this very often:
{% extends 'base.html' %}
Unfortunately this does not work for me. The ordering of the template loader loads a template from a different app first.
I have a default django project and application created from scratch with Django1.8.
What should I do:
use a different name like 'my_base.html'
alter the ordering of the template loader
other solution?
The easy way to solve this problem is to namespace your templates. Create an application and inside the application directory (where you have the default views.py) create a templates directory, and inside that directory create a subdirectory which is the name of the application.
Imagine you have a project myproj and an app called registration, then you would have:
.
├── manage.py
├── myproj
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
└── registration
├── admin.py
├── __init__.py
├── migrations
│ └── __init__.py
├── models.py
├── templates
│ └── registration
│ └── base.html
├── tests.py
└── views.py
Now even if you have another application with a template called base.html, you can always load the specific template you need with {% extends 'registration/base.html' %}
I'm working through the official Django tutorial. At the end of part two they have you customize the admin template just a bit (changing some heading text). I think I've done everything right, but apparently I haven't because the admin site looks exactly the same after running syncdb and restarting the server. My project directory (excluding the virtualenv part) looks like this:
mysite
├── manage.py
├── mysite
│ ├── __init__.py
│ ├── __init__.pyc
│ ├── settings.py
│ ├── settings.pyc
│ ├── urls.py
│ ├── urls.pyc
│ ├── wsgi.py
│ └── wsgi.pyc
├── polls
│ ├── admin.py
│ ├── admin.pyc
│ ├── __init__.py
│ ├── __init__.pyc
│ ├── models.py
│ ├── models.pyc
│ ├── tests.py
│ └── views.py
└── templates
└── admin
└── base_site.html
In settings.py I have these lines added to make the project use the template in templates/admin:
import os
PROJECT_PATH = os.path.realpath(os.path.dirname(__file__))
later:
TEMPLATE_DIRS = (os.path.join(PROJECT_PATH, 'templates'),)
I've tried several combinations of slashes and variations on assigning the value to PROJECT_PATH and TEMPLATE_DIRS, but haven't gotten anything to work. Each time I verified that it was actually making a filepath string (with a simple print statement).
To try to see what was going on I edited the original Django base_site.html it its admin folder and that changed my site, so it's obviously still using that. I've read several SO posts, and I don't really know what to do anymore.
Oh, and if it's relevant: Python 2.7.3 and Django 1.4.3
First thing I would try is deleting your *.pyc files they often contain stale information which sometimes can cause issues likes this.
If that isn't the case I would then double check your PROJECT_PATH which I believe is the issue here.
dirname gets you the containing directory. so if that line is in the settings.py it will return /path/to/inner/mysite the one inside the main mysite and since there is not templates directory in your inner mysite it wont work.
what you need to do is this.
PROJECT_PATH = os.path.realpath(os.path.dirname(os.path.dirname(__file__)))
Which will return you the outer mysite path when combined with templates it will return you the correct path.
Everything should then work.