Why doesn't my React-Django app detect static files? - django

I have created a working React + Django REST project and it works fine on my development machine. I have used the following method to make it work on my CentOS 7 server.
I created the build directory using npm run build and copied that to the Django project root folder.
I added the build directory on TEMPLATES list in Django settings to identify the index.html file.
I added build/static folder in STATICFILES_DIRS.
I added url(r'^.*', TemplateView.as_view(template_name='index.html')), line to the root URLS file to capture all url patterns and load the index file in build folder that contains the React app.
I run manage.py collectstatic to create a staticfiles folder with all static files.
I added the staticfiles folder to the Nginx conf file like following:
location /static/ {
root /home/michel/project/staticfiles;
}
I have restarted the nginx server.
I am using the Django server to load the index.html file and I expect that the staticfiles folder will contain necessary static files to load my React app.
However, when I visit www.mydomain.com it loads the index.html file, but does NOT load the React app on <div id='root'></div>. I know this because the footer of the index is shown, but the css for styling that footer is also not working.
I am guessing that I have a problem of making the static files being detected. Any solution?
EDIT
Here is the code that links my React app to the index.html file.
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
ReactDOM.render(<App />, document.getElementById('root'));
registerServiceWorker();
P.S. It is automatically generated by the create-react-app command.

Its probably because you don't understand the Nginx root directive.
This:
location /static/ {
root /home/michel/project/staticfiles;
}
Means if I request www.yourwebsite.com/static/style.css then Nginx is going to expect that file location to be
/home/michel/project/staticfiles/static/style.css
not
/home/michel/project/staticfiles/style.css

Related

Error running WSGI application, ModuleNotFoundError: No module named 'mysite'. Also not able to find Static files

I'm trying to deploy my website using pythonanywhere. I've given the correct path in wsgi file which is as follows (see code below). Still I'm getting a ModuleNotFoundError.
Also, it's not able to find Static files, however, they are at correct location.
Wsgi file code:
{
path = '/home/divyanshu964/portfolio/Personal_portfolio/'
if path not in sys.path:
sys.path.insert(0, path)
os.environ['DJANGO_SETTINGS_MODULE'] = 'Personal_portfolio.settings'
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()
}
Can someone help? Thanks.
Hello #DivyanshuRaghuwanshi to load static files you can set DEBUG=True inside settings.py but it's not a good practice to set DEBUG on in production so another way is to set your DEBUG=False and create STATIC_ROOT and configure it inside project root urls.py and than run python manage.py collectstatic command and than give path of your static root directory in pythonanywhere configuration
Apart from settings directly related to Django, there are some extra steps on PythonAnywhere.
wsgi file: you need to edit the file that is linked on the Web app page, not a file inside your project (check the docs here)
static files: set up static files mappings on the Web app page as well (check the docs here).

django Static files in production server

My problem is with a static files (img , styles). My code is working fine with no error with static files and the images appears when I run the server, but when I make the (debug = False) the images and styles disappear I ran my code on Linux server ubuntu.... How do I make the static files appear with the (debug=false)?
in settings.py that is my code
STATIC_URL = '/static/'
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'music/templates/'),
)
In my html file the image-tag is just like this:
<img src="{% static 'music/login.jpg' %}" width="300" height="300">
As Jon Clements commented, if debug=False then the Django app staticfiles is disabled. Usually in production one uses a dedicated web server (a server that is not running Django to serve static files). Hence, to solve your problem, an extra server should be set up to serve the static files.
Some high level steps:
Go to your django settings file and add a STATIC_ROOT which will be the directory where Django will place the static files;
Run python manage.py collecstatic for Django to collect all the static files and put them at the STATIC_ROOT directory;
Serve the files in this directory when a request contains your STATIC_URL in the URL (these requests will usually contain /static/ or something). For example, this can be done with an Nginx server or an Apache one as explained in Django docs:
https://docs.djangoproject.com/en/2.2/howto/deployment/wsgi/modwsgi/#serving-files
In terms of an Nginx config, one short snippet, just to illustrate such idea, could be something like:
server {
listen 80;
# hey Nginx, once you see something like /static/ in the url
# try to grab the file that is under the alias directory and
# return to the user
location /static/myapp/ {
alias /var/www/myproject/static/myproject/myapp/;
access_log true;
add_header Cache-Control "max-age=120";
}
}
To sum things up:
Django's staticfiles app is great for local development but is not really suitable for production apps.
Hence, serving static files should usually be done by a dedicated and separated server such as Nginx or an Apache one which requires some additional configuration to set these servers up.

Ignore SuspiciousFileOperation in Django

I am serving my vuejs SPA in django at /app/
Serving static files at /static/
My app is working fine served in django development, but, collectstatic fails.
My vue.config.js has:
module.exports = {
assetsDir: 'static',
}
Compiled CSS files have font urls like this:
url(../../static/fonts/materialdesignicons-webfont.ee2bb9f3.eot
This works in the browser because it can't go up 2 dirs but in the filesystem goes up 2 dirs instead of one.
Works fine in the browser, but can't be deployed. It throws SuspiciousFileOperation exceptions:
django.core.exceptions.SuspiciousFileOperation: The joined path (/mnt/c/Users/static/fonts/materialdesignicons-webfont.ee2bb9f3.eot) is located outside of the base path component (/mnt/c/Users/fede_/braced/staticfiles)
I am really stuck with this.

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

Identical and simple way of serving static files in development and production - is it possible?

Is it possible to have static files only in PROJECT_DIR/static directory without duplicates of static files in app dirs and without needing to do collectstatic command? On local computer Django dev server is used, in production - some other web server. From what I have read so far I decided that it's impossible, but maybe it's not true.
Of course it's possible.. the static files app is there to be useful. If you dont like "duplicates" (that's the whole point - you can have files per app, all merged into one area), don't use the staticfiles app.
Just use any folder, anywhere, as your assets folder. In production, serve it at some url, say MY_URL. In development, wire up your URLConf to serve files at your asset folder at MY_URL
https://docs.djangoproject.com/en/1.5/howto/static-files/#serving-files-uploaded-by-a-user
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = patterns('',
# ... the rest of your URLconf goes here ...
) + static('MY_URL', document_root='path-to-my-files')
This is the old school method of doing this, before staticfiles brought its goodness.
Are you sure you can't solve this problem by just using the staticfiles app? It's not much work to add in a python manage.py collectstatic --noinput in your deployment script.