Javascript with Django? - javascript

I know this has been asked before, but I'm having a hard time setting up JS on my Django web app, even though I'm reading the documentation.
I'm running the Django dev server. My file structure looks like this:
mysite/
__init__.py
MySiteDB
manage.py
settings.py
urls.py
myapp/
__init__.py
admin.py
models.py
test.py
views.py
templates/
index.html
Where do I want to put the Javascript and CSS? I've tried it in a bunch of places, including myapp/, templates/ and mysite/, but none seem to work.
From index.html:
<head>
<title>Degree Planner</title>
<script type="text/javascript" src="/scripts/JQuery.js"></script>
<script type="text/javascript" src="/media/scripts/sprintf.js"></script>
<script type="text/javascript" src="/media/scripts/clientside.js"></script>
</head>
From urls.py:
(r'^admin/', include(admin.site.urls)),
(r'^media/(?P<path>.*)$', 'django.views.static.serve', {'document_root': 'media'})
(r'^.*', 'mysite.myapp.views.index'),
I suspect that the serve() line is the cause of errors like:
TypeError at /admin/auth/
'tuple' object is not callable
Just to round off the rampant flailing, I changed these settings in settings.py:
MEDIA_ROOT = '/media/'
MEDIA_URL = 'http://127.0.0.1:8000/media'
UPDATE: I made some changes, but it's still not working:
settings.py:
ROOT_PATH = os.path.normpath(os.path.dirname(__file__))
urls.py:
(r'^media/(?P<path>.*)$', 'django.views.static.serve', {'document_root': os.path.join(settings.ROOT_PATH, 'site_media')}),
index.html:
<script type="text/javascript" src="/media/JQuery.js"></script>
<script type="text/javascript" src="/media/sprintf.js"></script>
<script type="text/javascript" src="/media/clientside.js"></script>
Filesystem:
mysite/
site_media/
JQuery.js
sprintf.js
clientside.js
__init__.py
settings.py
manage.py
-- etc
myapp/
-- app files, etc
When I go to a url like http://127.0.0.1:8000/media/sprintf.js, I get:
Page not found: /media/sprintf.js

But does that /media/ global directory exist? And have you placed in there a scripts subdirectories with the scripts you want to serve from there? What about the /scripts/... url from which you want to serve JQuery.js -- that doesn't seem to be served anywhere from your urls.py. If you (for whatever reason) want to serve scripts (or any other statically served file) from several different URL paths, all of those URL paths need to be matched in urls.py with the static-serving -- or else, do the normal things and serve them all from the /media/... root URL, and map that media root to the dir where you actually keep these files (in their respective subdirs, typically).
Django's docs about static serving (for development only, since it's documented as
Using this method is inefficient and
insecure. Do not use this in a
production setting. Use this only for
development.
so beware!-) seems pretty clear to me.

You may want to use absolute path for 'document_root' in urls.py if you want to use the development server to serve static files. MEDIA_ROOT and MEDIA_URL don't play any role here.
Here are my settings for your reference. I put all static media files under site_media/
mysite/
site_media/
css/
js/
images/
...
in settings.py:
ROOT_PATH = os.path.normpath(os.path.dirname(__file__))
in urls.py:
url(r'^media/(?P<path>.*)$', "django.views.static.serve", {'document_root':
os.path.join(settings.ROOT_PATH, 'site_media')})
You can move static files else where, just need to point 'document_root' to the correct path. Make sure comment out this url line for production deployment.

Actually, you can put your Javascript files (and all your static content) anywhere you want. I mean, Django does not impose a standard on where to place them, after all they won't be handled by Django, they'll be served by the webserver.
Said that, It's a good idea to keep them somewhere close to the project's files. I'd recommend to keep them in a sibling folder to your Django code. Same with MEDIA_ROOT.
It is a good idea to decouple your static files from python files because now you can put them in totally separate folders in a production environment and easily give different access to static files and python code (say FTP access, or permissions).
Something to keep in mind is that the settings' MEDIA_ROOT is the place where user's media files (that is uploaded content) will be placed, these are not your static project files, these are whatever files your Django app uploads (avatars, attachments, etc).
Proposed folder structure:
mysite.com/
media/ - User media, this goes in settings.MEDIA_ROOT
static/ - This is your static content folder
css/
js/
images/
templates/
project/ - This is your Django project folder
__init__.py
manage.py
settings.py
myapp/
__init__.py
...files..py
See the other responses recommendation on using Django's serve() function for development enviroment. Just make sure you add that url() to your urlpatterns under a settings.DEBUG is True conditional.
As for your templates, it's a good idea to use a context processor to send your static file's path to all your templates.

I serve javascript via static. So I have something in my urls.py like
(r'^static/(?P<path>.*)$', 'django.views.static.serve', {'document_root': os.getenv('STATIC_DIR')})
So JS urls look like /static/js/blah.js, CSS urls look like /static/css/blah.css, etc. I have Apache handle the static directory when running in production to avoid any issues with Django's static serving mechanism.

For my development work, I use Django's built-in server, but I read the media files from the same directory as they would be in production (/srv/nginx/sitename/media/). So I clone the exact directory structure of my production server on my computer at home, letting me seamlessly push changes to production without having to change anything.
I keep two different settings.py files, though. My home settings.py file has my local database settings, a different MEDIA_URL setting, and DEBUG set to True. I use this in my URLs file to enable the server view for local media (since I don't run nginx on my home computer).
In urls.py:
if settings.DEBUG:
urlpatterns += patterns('',
(r'^media/(?P<path>.*)$', 'django.views.static.serve',
{'document_root': settings.MEDIA_ROOT}),
)
From settings.py (note, MEDIA_ROOT must be an absolute path):
# Absolute path to the directory that holds media.
# Example: "/home/media/media.lawrence.com/"
MEDIA_ROOT = '/srv/nginx/<sitename>/media/'
# URL that handles the media served from MEDIA_ROOT. Make sure to use a
# trailing slash if there is a path component (optional in other cases).
# Examples: "http://media.lawrence.com", "http://example.com/media/"
MEDIA_URL = 'http://127.0.0.1:8000/media/'
TEMPLATE_CONTEXT_PROCESSORS = (
# I've taken out my other processors for this example
"django.core.context_processors.media",
)
In a template:
<link rel="stylesheet" href="{{ MEDIA_URL }}css/form.css" />{% endblock %}
Filesystems:
/srv/nginx/<sitename>
/media <-- MEDIA_ROOT/MEDIA_URL points to here
/css
base.css
form.css
/img
/js
Oh, also: if that's a direct copy from your urls.py file, you forgot a comma after your serve view, that's causing your TypeError ;)

The error 404 occurs because MEDIA_ROOT requires absolute path, not relative. The server is trying to access /media in your filesystem, which is obviously not what you want.
Try this instead:
import os
PROJECT_PATH = os.path.realpath(os.path.dirname(__file__))
MEDIA_ROOT = os.path.join(PROJECT_PATH, 'site_media')
MEDIA_URL = '/media/'

This is a structure I use in a project separated into multiple apps. It's a good practice to adapt this structure right at the start -- you don't want global rearrangement when you need to add another app to your project.
/media
favicon.ico
robots.txt
/upload # user uploaded files
/js # global js files like jQuery
/main_app
/js
/css
/img
/other_app
/js
/css
/img
Then I use excellent StaticMiddleware from django-annoying to serve files. settings.py:
import os
import annoying
MEDIA_ROOT = os.path.join(os.path.dirname(__file__), "media")
MIDDLEWARE_CLASSES = (
'annoying.middlewares.StaticServe',
#...
)

I just remove the '^',
"r'static/" instead of "r'^static/".
It's works for me ,good luck.
url(r'static/(?P<path>.*)$', 'django.views.static.serve',
{ 'document_root': the_path }),

Related

Basic Python Web application giving jinja2 error [duplicate]

I am trying to render the file home.html. The file exists in my project, but I keep getting jinja2.exceptions.TemplateNotFound: home.html when I try to render it. Why can't Flask find my template?
from flask import Flask, render_template
app = Flask(__name__)
#app.route('/')
def home():
return render_template('home.html')
/myproject
app.py
home.html
You must create your template files in the correct location; in the templates subdirectory next to the python module (== the module where you create your Flask app).
The error indicates that there is no home.html file in the templates/ directory. Make sure you created that directory in the same directory as your python module, and that you did in fact put a home.html file in that subdirectory. If your app is a package, the templates folder should be created inside the package.
myproject/
app.py
templates/
home.html
myproject/
mypackage/
__init__.py
templates/
home.html
Alternatively, if you named your templates folder something other than templates and don't want to rename it to the default, you can tell Flask to use that other directory.
app = Flask(__name__, template_folder='template') # still relative to module
You can ask Flask to explain how it tried to find a given template, by setting the EXPLAIN_TEMPLATE_LOADING option to True. For every template loaded, you'll get a report logged to the Flask app.logger, at level INFO.
This is what it looks like when a search is successful; in this example the foo/bar.html template extends the base.html template, so there are two searches:
[2019-06-15 16:03:39,197] INFO in debughelpers: Locating template "foo/bar.html":
1: trying loader of application "flaskpackagename"
class: jinja2.loaders.FileSystemLoader
encoding: 'utf-8'
followlinks: False
searchpath:
- /.../project/flaskpackagename/templates
-> found ('/.../project/flaskpackagename/templates/foo/bar.html')
[2019-06-15 16:03:39,203] INFO in debughelpers: Locating template "base.html":
1: trying loader of application "flaskpackagename"
class: jinja2.loaders.FileSystemLoader
encoding: 'utf-8'
followlinks: False
searchpath:
- /.../project/flaskpackagename/templates
-> found ('/.../project/flaskpackagename/templates/base.html')
Blueprints can register their own template directories too, but this is not a requirement if you are using blueprints to make it easier to split a larger project across logical units. The main Flask app template directory is always searched first even when using additional paths per blueprint.
I think Flask uses the directory template by default. So your code should be like this
suppose this is your hello.py
from flask import Flask,render_template
app=Flask(__name__,template_folder='template')
#app.route("/")
def home():
return render_template('home.html')
#app.route("/about/")
def about():
return render_template('about.html')
if __name__=="__main__":
app.run(debug=True)
And you work space structure like
project/
hello.py
template/
home.html
about.html
static/
js/
main.js
css/
main.css
also you have create two html files with name of home.html and about.html and put those files in templates folder.
If you must use a customized project directory structure (other than the accepted answer project structure),
we have the option to tell flask to look in the appropriate level of the directory hierarchy.
for example..
app = Flask(__name__, template_folder='../templates')
app = Flask(__name__, template_folder='../templates', static_folder='../static')
Starting with ../ moves one directory backwards and starts there.
Starting with ../../ moves two directories backwards and starts there (and so on...).
Within a sub-directory...
template_folder='templates/some_template'
I don't know why, but I had to use the following folder structure instead. I put "templates" one level up.
project/
app/
hello.py
static/
main.css
templates/
home.html
venv/
This probably indicates a misconfiguration elsewhere, but I couldn't figure out what that was and this worked.
If you run your code from an installed package, make sure template files are present in directory <python root>/lib/site-packages/your-package/templates.
Some details:
In my case I was trying to run examples of project flask_simple_ui and jinja would always say
jinja2.exceptions.TemplateNotFound: form.html
The trick was that sample program would import installed package flask_simple_ui. And ninja being used from inside that package is using as root directory for lookup the package path, in my case ...python/lib/site-packages/flask_simple_ui, instead of os.getcwd() as one would expect.
To my bad luck, setup.py has a bug and doesn't copy any html files, including the missing form.html. Once I fixed setup.py, the problem with TemplateNotFound vanished.
I hope it helps someone.
Check that:
the template file has the right name
the template file is in a subdirectory called templates
the name you pass to render_template is relative to the template directory (index.html would be directly in the templates directory, auth/login.html would be under the auth directory in the templates directory.)
you either do not have a subdirectory with the same name as your app, or the templates directory is inside that subdir.
If that doesn't work, turn on debugging (app.debug = True) which might help figure out what's wrong.
I had the same error turns out the only thing i did wrong was to name my 'templates' folder,'template' without 's'.
After changing that it worked fine,dont know why its a thing but it is.
You need to put all you .html files in the template folder next to your python module. And if there are any images that you are using in your html files then you need put all your files in the folder named static
In the following Structure
project/
hello.py
static/
image.jpg
style.css
templates/
homepage.html
virtual/
filename.json
When render_template() function is used it tries to search for template in the folder called templates and it throws error jinja2.exceptions.TemplateNotFound when :
the file does not exist or
the templates folder does not exist
Create a folder with name templates in the same directory where the python file is located and place the html file created in the templates folder.
Another alternative is to set the root_path which fixes the problem both for templates and static folders.
root_path = Path(sys.executable).parent if getattr(sys, 'frozen', False) else Path(__file__).parent
app = Flask(__name__.split('.')[0], root_path=root_path)
If you render templates directly via Jinja2, then you write:
ENV = jinja2.Environment(loader=jinja2.FileSystemLoader(str(root_path / 'templates')))
template = ENV.get_template(your_template_name)
After lots of work around, I got solution from this post only,
Link to the solution post
Add full path to template_folder parameter
app = Flask(__name__,
template_folder='/home/project/templates/'
)
My problem was that the file I was referencing from inside my home.html was a .j2 instead of a .html, and when I changed it back jinja could read it.
Stupid error but it might help someone.
Another explanation I've figured out for myself
When you create the Flask application, the folder where templates is looked for is the folder of the application according to name you've provided to Flask constructor:
app = Flask(__name__)
The __name__ here is the name of the module where application is running. So the appropriate folder will become the root one for folders search.
projects/
yourproject/
app/
templates/
So if you provide instead some random name the root folder for the search will be current folder.

Cannot find route to 'js' within 'Public' folder...using'views'?

I have a structure similar to the following:
--Public
--js
--main.js
--Views
--Pages
--about.ejs
--Partials
--head.ejs
--header.ejs
--footer.ejs
--Server.js
In my HTML (.ejs) page (about.ejs) I have the path to use the 'main.js' within the 'Public' folder defined as
...
<script src="/public/js/main.js"></script>
...
However my tests indicate this is failing. I simply attempt to change the 'innerHTML' of a paragraph on the 'about.ejs' page within the 'main.js' as the test...since nothing happens I assume the HTML (.ejs) page is not able to find the javascript file within the 'Public' folder. Any help appreciated greatly...this is immensely frustrating.
I think you use NodeJs. Probably, you need to serve static files.
Expressjs's serving static files
Base on your project structure, your Public directory is in titlecase
Try:
<script src="/Public/js/main.js"></script>

CSS file not loading (Django, python)

Here's the code I have:
In the HTML file:
<link rel="stylesheet" href={% static 'css.css' %}" >
In settings.py:
STATICFILES_DIRS = (os.path.join(BASE_DIR, 'static'),)
The css.css file is located in the static directory which is in the same directory as manage.py ,
So why isn't the css file loading?
There is also a js file which doesn't seem to be loading either, and it's in the same directory as the CSS file and I'm loading it in with the same method as the CSS file.
Also, my pc isn't currently connected to WiFi, in case it makes a difference. I'm working with localhost.
Have you configured your Static files URL.
According to best practice
STATIC_URL = '/static/'
Actually the above is too little information to help anyway. Can you tell us the application environment (production/development) etc because there are specific configurations for each in Django. Also please provide code using the code markup. Assuming you are using Django 1.11, read this for a better understanding or better yet see a tutorial for beginners

Django internationalization not working only on javascript static files

Background info: django 1.6.2, python 2.7.5
I recently started applying internationalization to my django project. I've managed to make it work in the models, views, and templates of an app (called metrics). However, when I try to apply internationalization on the static js files, gettext() does not seem to work since it always returns the string that I pass to it, ignoring the browser language. On the other hand, the {% trans ... %} tags in the html template (which uses those js static files) get translated correctly. This indicates that the issue resides in the internationalization of my js static files. Could anybody offer any guidance or suggestions?
This is a summary of my project configuration:
In the project settings I included:
MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.locale.LocaleMiddleware',
'django.middleware.common.CommonMiddleware',
...
)
LANGUAGES = (
('es', _('Spanish')),
('en', _('English')),
)
LOCALE_PATHS = (
os.path.join(BASE_DIR,'locale'),
os.path.join(BASE_DIR,'metrics/'),
)
USE_I18N = True
USE_L10N = True
The djangojs.po and .mo files concerning the js static files are located in the locale folder sitting in my root directory while the django.po and .mo files sit in the locale/es/LC_MESSAGES folder within my app. I ran django-admin.py makemessages -l es and django-admin.py makemessages -d djangojs -l es from the appropriate directory and django-admin.py compilemessages from both (even though that may be redundant...). Note that the .po files have no FUZZY tags.
In the project's url.py file I included:
js_info_dict = {
'packages': ('metrics',),
}
urlpatterns = patterns('',
url(r'^jsi18n/$', 'django.views.i18n.javascript_catalog', js_info_dict),
...
)
Perhaps this part is wrong since my djangojs.po and .mo files are in the root directory, but I tried locating them in my app directory and it did not work either.
Finally, an example of gettext use in my static js file (using d3js):
svg.append("g").append("text")
.attr({"x":0,"y":17})
.style({"text-anchor":"middle","fill":"black"})
.text(gettext('Schedule'));
Any suggestions? And sorry about the huge write-up but I am trying to provide as much info as possible.

Django - development server not serving admin static files

Everything was perfectly working fine, but after a symlink for the MySQL python the admin CSS and JS disappeared.
I tried to Symlink the admin static folder in the Django folder.
I copied and pasted the CSS, images, JS to the static folder but it didn't work also.
This is really strange, Django documentation mentions that "Django development server automatically serves the static files of the admin app" but this isn't the case anymore. It was perfectly working fine.
Anyone faced such an issue before ?
Thanks.
Django serves the static files, but not without a little editing on settings.py. Are you sure you haven't changed these parameters listed below?
MEDIA_ROOT = '/absolute/path/Project/App/'
MEDIA_URL = '/media/'
STATIC_ROOT = '/absolute/path/Project/App/templates/' -> inside this folder should be your static content, accordingly to this example
STATIC_URL = '/static/'
#URL prefix for admin static files -- CSS, JavaScript and images.
ADMIN_MEDIA_PREFIX = '/static/admin/'
And in your template, you should use something like this:
{{ STATIC_URL }}templates/styles_folder/styles.css
Django is probably looking for these files in the wrong directory. If it can't show your files, is pretty much because it can't find them where you told they would be.

Categories