In Django1.8 project, can't find static files in different application - django

I have started learning Django1.8.
In my project, I have 2 applications - one is account app and the other is images app. Each application directory contains static directory.
The static directory structures of 2 apps are as follows.
account app
static/
css/
base.css
images app
static/
js/
bookmarklet.js
css/
bookmarklet.css
When I go to http://127.0.0.1:8000/static/css/base.css in account app on the browser, I can find base.css file on the browser.
But when I go to http://127.0.0.1:8000/static/js/bookmarklet.js in images app, I get 404 error.
'js\bookmarklet.js' could not be found
I'm not sure how can I fix this issue.

When I add STATICFILES_DIRS in settings.py file, I can fix this issue.
STATICFILES_DIRS = (
os.path.join(BASE_DIR, "static"),
)

Related

Static File and Media Accessing issue while Deploying Django app in Production Environment

While deploying django app on production environment in openlitespeed server, static files and media files not found.
App is woking fine in development environment in local, but after uploading it to server, static content and media files are not accessible.
I have updated my static url as follow:
STATIC_URL = '/public/static/'
STATIC_ROOT = '/home/domain.com/app/public/static
Where app is the project location.
I am getting 404 for error for all static and media files:
Failed to load resource: the server responded with a status of 404 ()
When I try collectstatic I am getting following error on terminal:
django.core.exceptions.ImproperlyConfigured: You're using the staticfiles app without having set the STATIC_ROOT setting to a filesystem path.
I tried many options, none of the options worked.
Any solution will be highly appreciated
I assume the missing apostrophe is just missclick here in SO if it worked on development. This is how you should handle STATIC_ROOT in Django >= 4.0:
STATIC_ROOT = BASE_DIR / 'app/public/static'
Older versions:
STATIC_ROOT = os.path.join(BASE_DIR, 'app/public/static')
You are missing inverted comma end of your code
STATIC_ROOT = '/home/domain.com/app/public/static
it should be
STATIC_ROOT = '/home/domain.com/app/public/static'
Problem Solved:
STATIC_ROOT = BASE_DIR / 'app/public/static'
I updated static_root convention according to Django >= 4.0 and on openlitespeed server every static content should be placed inside /public folder which is mandatory rule if we do not edit default configuration. I created /public folder and moved my static and media folder. And then did the collectstatic. Problem resolved.

Using static folding inside app folding Django

I have a static directory inside my apps folder. I added this line of code to my projects settings.py file
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "static"),
'/var/www/static/',
]
The file continues to result in a 404 not found. I'm getting stuck, what should I do?
It probably isn't mistake in your static files settings. But to be sure the relevant settings for static folder in app directories is STATICFILES_FINDERS https://docs.djangoproject.com/en/2.1/ref/settings/#staticfiles-finders. But the AppDirectoriesFinder should be present by default so it is probably OK.
Your problem is probably in your URL scheme:
For development purposes make sure you have django.contrib.staticfiles in your installed apps, DEBUG = True and STATIC_URL = '/static/' (or something similar). Then you should be able access the files.
For deploying it is more complicated but essentially you have setup STATIC_ROOT, before starting the server run python manage.py collectstatic command which will copy all static files to one location and then setup your server (Nginx) to serve the files from this folder under /static/ URL. Here is the official documentation https://docs.djangoproject.com/en/2.1/howto/static-files/#deployment
Note: if your app is foo and you have bar file in your static directory under foo app the URL for the file will be /static/foo/bar.

Heroku: Deploying Django Rest Framework + Vue

I have a project made with Django (only DRF API) and Vue js.
I have this project structure:
root_directory/
├── project_name/
│ ├── settings.py
│ ├── ...
├── front_end/
│ ├── ... vue files generated with CLI 3 ...
└── api/
└── ... api app files ...
I want to deploy this project using heroku and my biggest problem is: I don't know how to serve static files (vue app files).
In heroku docs is specified that I should use django staticfiles serving with whitenoise package (apart from hosting them in S3).
But here comes another problem: vue-cli provided me a index.html file where everything gets injected when I run npm run build, so I can't access {% static 'example.js' %} in index.html directly, cause it is not the index.html that I should use, it is the one in dist/ folder, of course. But there everything gets minified and too complicated for me to handle. I think npm run build would throw an error if it sees something like {% %} in public/index.html.
I can't figure out how can I manage to deploy this project with heroku.
What would be the best practice to deploy it in this situation?
Thanks in advance.
Besides mixing up both applications, you could host your Django app and Vue app separated from each other.
Use Django to connect to a database and provide the data (e. g. JSON) via REST API (backend).
Consume the data from the REST endpoints with your Vue app (frontend).
Here are some starting points (as you mentioned Heroku):
Deploy Django:
https://devcenter.heroku.com/articles/deploying-python
Deploy Vue:
https://medium.com/netscape/deploying-a-vue-js-2-x-app-to-heroku-in-5-steps-tutorial-a69845ace489
Some nice library to consume the data from the REST API with Vue:
https://github.com/axios/axios
add this to your Middleware in settings.py
'whitenoise.middleware.WhiteNoiseMiddleware',
make sure you add this STATICFILES_DIRS and STATICFILES_STORAGE in your settings.py after STATIC_URL
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static')
]
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
Note: make sure you install this: pip install django-heroku
Did you check - Timestrap Application ( https://github.com/overshard/timestrap). They do have Heroku based demo instance: https://timestrap.herokuapp.com/
This Application is based on Vuejs and Django - it will give good idea on how to go about it.
Enjoy
You should be able to handle this using WhiteNoise 4.0 and above and a few settings. For example:
# Enable this so that WhiteNoise will serve `index.html` files at the directory root
WHITENOISE_INDEX_FILE = True
# Set this to wherever npm puts your final files
WHITENOISE_ROOT = os.path.join(BASE_DIR, 'dist')

Using Django static() to generate audio files' URLs in production

I'm trying to get my Django app to play audio files (supposedly) uploaded by users via a form. Said files are tied to a model :
# models.py
class Doc(models.Model):
# ...
tape = models.FileField()
The uploading and saving parts are working fine, and the files are stored where they should be :
- djangoproject
|
- docapp
|
- media <- here
So, in order to get where I want, I added these two lines to the settings.py file MEDIA_ROOT = os.path.join(BASE_DIR, 'docapp/media/') and MEDIA_URL = 'docapp/media/'.
I hoped to be able to link to the audio files thus:
# templates/docapp/index.html
...
<audio src='{{ doc.tape.url }}' controls></audio>
Unfortunately, this wasn't working because the link generated by doc.tap.url (http://localhost/docapp/media/filename.aac) was returning a 404 error.
After a lot of googling I found this answer, which I happily copy-pasted into my app ... and it worked. This is the code in question :
# urls.py
from django.conf import settings
from django.conf.urls.static import static
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
The problem is that I'm not comfortable with inserting code in my apps that I don't understand. I did some research about the static() function and all I could get is this :
Helper function to return a URL pattern for serving files in debug mode
Does this mean that the static function should not be used in production? If so, what should I be using in production? And what exactly does it do?
EDIT To be clear, the generated URL after injecting the solution is the same as the one generated without it. Yet, it only works when the static() function is present.
EDIT 2 I forgot to mention that the 404 errors persisted even after I chmoded the media folder to allow others to read-access it.
Thanks in advance!
You shouldn't do anything. No errors no problem. The docs write about development server and serving static files AND that it is for development only. In a production environment you configure your server (Apache, NGNIX or third party like S3) to serve the files. That's all.
Try to configure media files and access the file via it's url. If it works, try the {{ doc.tape.url }} template tag.
In your development environment your media may live in /media/ (route and directory). While on production it may be something like media.example.com. Running Django with the settings for that environment will change all static/media domains and paths to their correct locations.
You may split settings file into a settings file for each environment (production, acceptance, development). Like this:
project/
settings/
__init__.py
base.py
local.py
staging.py
test.py
production.py
You can run your project with a specific env: ./manage.py runserver --settings=project.settings.development. Do not repeat yourself and put development specific settings in development.py and from base import * so that base.py contains the default settings.
This project and settings layout is taken from the book Two Scoops of Django. It is just an example. Adjust to your own needs.
Yes, django.conf.urls.static.static is only for development and not for production. For production, you should just need to configure your MEDIA_URL and MEDIA_ROOT settings and have your webserver serve the MEDIA_ROOT directory in the MEDIA_URL path.
Basically adding that in the URL urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) will make the media files in the URL existing. Try removing that and visit your media file in the URL and you will receive a 404 not found. It's very similar to the concept that you are inserting a view for rendering the media files

Django project hierarchy/organization

I am new to Django and starting a project, and I would like to do it the right way.
I would like to know what you think is best practice for organizing a project.
Here are some questions I have:
How do I separate the static resources from the Python code so that I don't waste time processing the static content through Django?
As apps are reusable modules, they are not really tight to a project, so should they be located in the project directory, or in another directory that would contain all my "homemade" apps?
Are templates considered to be static or dynamic content?
Here is my current file hierarchy:
webapps/
myproject/
apache/
bin/
lib/
templates/
app1/
app2/
src/
app1/
app2/
__init.py
settings.py
urls.py
manage.py
myproject.wsgi
admin/
static/
css/
img/
What do you think?
What would be better?
Thanks!
Your directory structure could also depend on what version of django that you're using. If you're using django 1.3, handling static content has changed slightly. Your templates could also be arranged separately.
The following only applies for django 1.3.
Within an app directory:
...
app1/
static/
app1/
templates/
app1/
models.py
...
views.py
If you use the new django.contrib.staticfiles application, your settings may look something like this:
MEDIA_ROOT = path.join(ROOT_PATH,'uploaded_media/')
MEDIA_URL = '/uploaded_media/'
# static content is collected here, and served from here, but don't add stuff manually here! add to staticfiles_dirs
STATIC_ROOT = path.join(ROOT_PATH, 'collected_static/')
ADMIN_MEDIA_PREFIX = '/static/admin/'
STATIC_URL = '/static/'
# Additional locations of static files
STATICFILES_DIRS = (
path.join(ROOT_PATH, 'src/extra_static/'),
)
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
)
Similarly, your templates can be loaded directly from an INSTALLED_APP:
TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader'
)
TEMPLATE_DIRS = (
path.join(ROOT_PATH,'src/templates/'),
)
The two strategies above mean that templates and static content can live within their specific app directories. In Development, using contrib.staticfiles, static content can be served directly from your application folders. In production, there is a management command to collect all the app directory static content to /path/to/project/collected_static/, and you can point your web server at that directory to serve static content.
For pre-packaged libraries, using virtualenv and pip is a great idea. Otherwise, I like to keep libraries in a lib directory within the project root directory. It makes referencing the source, templates, and static content extremely convenient, rather than installing to site-packages (especially when not using virtualenv).
So, re-arranging your project structure:
webapps/
myproject/
apache/
bin/
lib/
collected_static/
uploaded_media/
myproject.wsgi
src/
templates/ # lib template overrides and site wide templates
base.html
lib_1/
nav.html
extra_static/
lib_1/ # libs that dont support django 1.3 static
js/
css/
settings.py
settingslocal.py # keep developer specific settings here
urls.py
manage.py
app1/
__init.py
static/
app1/
js/
css/
templates/
app1/
My designer doesn't want to go hunting everywhere (all over the python path) for template files. My template layout follows yours in that there is one template folder and all the apps go below that. Each app has its own base.html that extends basebase.html.
Here lately I've started following the pinax model of an apps folder, and all apps go in there. The reason for this is purely aesthetic since Wing shows me a tree, all my apps are clustered together in that part of the tree. What I didn't like was an app that sorted out alphabetically after templates or media or site_media. Scrolling up and down the tree slowed me down. By putting all the apps into one place in the tree, git commit -m "feature notes" apps checkins in the code changes too which is another plus.
webapps/
myvirtenv/
bin/
lib/
myproject/ <- Source control starts here
site_media/
collected_static/
js/
css/
img/
uploaded_media/
deploy/
myproject.wsgi
procmail scripts
apache site files # linked from /etc/apache2/sites-endabled
apps/
app1/
templates/ <- This should be here, but in practice I just leave in templates below
app1/
app2/
templates/ # lib template overrides and site wide templates
basebase.html <- I changed the name to help my designer
app1/
app2/
settings.py
gethostname()_local_settings.py # keep machine specific settings here
urls.py
manage.py
requirements
base.txt
project.txt
There were too many base.html files and talking about it was difficult, so basebase.html was born and we've been happy with that ever since.
I haven't had any static files that didn't work with the staticfiles app. I was using that app with 1.2. I haven't gone back and done the 1.3 static folders yet but I probably will in the next few months as things get worked on.
I got the requirements folder trick from pinax.
Create VirtualENV
git clone url
pip install -r requirements\base.txt -r requirements\project.txt
manage syncdb (if using sqlite, otherwise you have to do db creation tasks first)
symlink from /etc/apache2
reload apache config
Profit!
You've had some good thoughts here. My first reaction is to ask what that admin directory is doing? The admin is part of Django, and doesn't need a separate module - and the app-specific admin.py files need to live within their respective apps.
To answer your questions:
separating static and dynamic: this is done at the level of your web server configuration. In your case, your apache virtualhost conf needs to have an entry for the webapps/static directory, but not for anything else. The documentation has a good example.
If the apps really are completely decoupled from your project, then yes they could live outside it, as long as you put them onto the Pythonpath. One good way is to keep them in separate code repositories, and install them into your project with pip and virtualenv. However, I think you'll find that many of your apps will be project-specific, so live within your project directory.
Templates are very definitely dynamic content. If you serve them directly with Apache, they won't be parsed, so your users will see the code for the variable and block codes rather than the values.