I'm new to Django and to Python, and I've just completed Django's "build your first app" tutorial. I found it fantastic. However it never spoke about stylesheets, javascripts or anything of the like.
Where should they go? Currently my project directory looks like this:
myproject
+app1
+app2
+myproject
+public
+css
+img
+js
+templates
Am I doing it correctly? I would like to stick to Django/Python standards as much as possible. Also, if I would like to include certain styles and scripts in all of my templates, how can I do that? Let's say I'm using Bootstrap.
You should probably take a closer look at Managing static files.
Basically you can put a static folder in each of your apps (similar to your template folders) and the more general stuff (base.css, project-wide icons, jquery-plugins) in a static folder in your project root.
So the layout might look like this:
myproject
+app1
+static
+app1
+css
+js
+app2
+static
+css
+img
Once you deploy your project you can use, the collectstatic-command from contrib.staticfiles to collect all your static files to a single directory (STATIC_ROOT) where you can serve it from.
I prefer to call the +public folder +static, and put the +template (app specific) folder inside the application that is using them (so to avoid confusion and to be able to use a template with a different name twice), also I don't understand why you put +myproject inside your root project.
Related
Currently, collecstatic gathers all files of the project's Apps in one directory (STATIC_ROOT).
What should be done to keep the project structure for the static files:
STATIC_ROOT/App1
..
STATIC_ROOT/Appn
STATIC_ROOT/App3
thanks
The documentation recommends namespacing static files:
Static file namespacing
Now we might be able to get away with putting our static files directly in my_app/static/ (rather than creating another my_app subdirectory), but it would actually be a bad idea. Django will use the first static file it finds whose name matches, and if you had a static file with the same name in a different application, Django would be unable to distinguish between them. We need to be able to point Django at the right one, and the easiest way to ensure this is by namespacing them. That is, by putting those static files inside another directory named for the application itself.
Make sure to create an inner directory named after your app and put your files in there, e.g.
my_app/
static/
my_app/ ← This directory
file1
file1
...
Thank you chris,
I find exactly the solution as indicated here: How should I structure my static app files in Django?
I have just replace STATICDIR_FILES by :
STATICFILES_FINDERS = [
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
]
We are building uServices based on tornado. There are some routes which are common for all uServices, for the time being health and docs. The docs route is built using Swagger. That means, the swagger route, and associated assets, are part of our common library (but not the documentation itself, which is uService related), which is simply a requirement to our uServices.
Since swagger needs static assets, and each uService needs its own static assets too, I have a problem: my static assets are coming from two completely different places. I have found a (very inconvenient) hack to solve this:
track static assets in the common repo
track static assets in the uService repo
when deploying, copy those static assets, from both sources, to a deployment static folder (and hope that there are no clashes)
specify the deployment static folder as the static_path
Step 3 is quite complex, because it involves pip-installing the common library, finding the assets there (already a hack), and copying them around:
install the common library with pip
look for the location of the installed library (site-packages)
copy the static assets to the deployment static folder
It would be much easier if, as happens with the template_path, it would be possible to have a per-application static folder:
> Return None to load templates relative to the calling file.
I have been searching the web, and it seems this is not possible, but I wanted to double check.
An alternative would be to simplify asset extracting from a packaged python module, but not sure what is the preferred method to do this, without having to recur to hacks searching in the virtualenv for the site-packages.
It's not possible to do this with the static_path setting, but as long as you don't require the static_url() function, you can create multiple StaticFileHandler entries in your URLSpec list:
Application([
('/static1/(.*)', tornado.web.StaticFileHandler, dict(path='static1')),
('/static2/(.*)', tornado.web.StaticFileHandler, dict(path='static1')),
])
As a substitute for static_url, you can call StaticFileHandler.make_static_url and pass it the arguments that would have been global if you were using static_path.
I got a bit confused, because when I use the generic ListView class, Django is looking for "appname/objectname_list.html" inside the "appname/templates" folder. This results in:
appname/templates/appname/objectname_list.html
If I supply "template_name", it does not require the subfolder inside the templates folder anymore.
Why doesn't it find the objectname_list.html inside the "templates" folder like before in 1.3 ? Did I configure something wrong or did they change the place where I'm supposed to put my templates as well ? In 1.3 I used to place template html files inside "appname/templates" directly instead of using a subfolder.
For me it does not make sense to use another subfolder with the name of the app, where the templates folder is already in. Or am I missing something useful ?
I could not find anything about it in the release notes.
I don't think this is 1.4 specific. If you will want your template in a subfolder, specify template_name = 'subfolde/template.html'
Regarding template dirs, from the docs:
... For each app in
INSTALLED_APPS, the loader looks for a templates subdirectory. If the
directory exists, Django looks for templates in there.
So the actual dir is:
projectname/appname/templates/appname/objectname_list.html
^^^ ^^^
This helps you keep everything inside the app folder and does not require you to configure anything,
This also means that if you have apps foo, bar and baz, you can still have one templates dir under one of the apps:
myproj/foo/templates/foo/...
myproj/foo/templates/bar/...
myproj/foo/templates/baz/...
I have my template folder with all html templates lieing together in the template folder with no directory structure as such.
I decided to arrange them on per app basis, but:
A template with template-tags belong to different apps.
Eg:
Login page(Login app) includes a banner that belongs to UserActivity [User activity app]. So, if I include the login template in login folder in templates, then it will be including stuff across other app's template folder.
How should I structure so that all that referred stays in 1 place organized ?
Feel free to ask for more info.. :)
Organizing your templates in subdirectories is definitely they way to go, but I am not sure if you can really reach the level of separation you are looking for.
If your apps depend on each other you'll always have includes and tags from other apps. So i'd put the templates to the app they belong to.
But maybe the docs about template loaders can help you clarify your structure.
For example the app_directories.Loader
Loads templates from Django apps on the filesystem. For each app in
INSTALLED_APPS, the loader looks for a templates subdirectory. If the
directory exists, Django looks for templates in there.
This means you can store templates with your individual apps. This
also makes it easy to distribute Django apps with default templates.
So you could put app-specific templates in in your app directories and keep your general templates (base.html, etc.) in the top level template dir of your project.
I started an application in Google App Engine right when it came out, to play with the technology and work on a pet project that I had been thinking about for a long time but never gotten around to starting. The result is BowlSK. However, as it has grown, and features have been added, it has gotten really difficult to keep things organized - mainly due to the fact that this is my first python project, and I didn't know anything about it until I started working.
What I have:
Main Level contains:
all .py files (didn't know how to make packages work)
all .html templates for main level pages
Subdirectories:
separate folders for css, images, js, etc.
folders that hold .html templates for subdirecty-type urls
Example:
http://www.bowlsk.com/ maps to HomePage (default package), template at "index.html"
http://www.bowlsk.com/games/view-series.html?series=7130 maps to ViewSeriesPage (again, default package), template at "games/view-series.html"
It's nasty. How do I restructure? I had 2 ideas:
Main Folder containing: appdef, indexes, main.py?
Subfolder for code. Does this have to be my first package?
Subfolder for templates. Folder heirarchy would match package heirarchy
Individual subfolders for css, images, js, etc.
Main Folder containing appdef, indexes, main.py?
Subfolder for code + templates. This way I have the handler class right next to the template, because in this stage, I'm adding lots of features, so modifications to one mean modifications to the other. Again, do I have to have this folder name be the first package name for my classes? I'd like the folder to be "src", but I don't want my classes to be "src.WhateverPage"
Is there a best practice? With Django 1.0 on the horizon, is there something I can do now to improve my ability to integrate with it when it becomes the official GAE templating engine? I would simply start trying these things, and seeing which seems better, but pyDev's refactoring support doesn't seem to handle package moves very well, so it will likely be a non-trivial task to get all of this working again.
First, I would suggest you have a look at "Rapid Development with Python, Django, and Google App Engine"
GvR describes a general/standard project layout on page 10 of his slide presentation.
Here I'll post a slightly modified version of the layout/structure from that page. I pretty much follow this pattern myself. You also mentioned you had trouble with packages. Just make sure each of your sub folders has an __init__.py file. It's ok if its empty.
Boilerplate files
These hardly vary between projects
app.yaml: direct all non-static requests to main.py
main.py: initialize app and send it all requests
Project lay-out
static/*: static files; served directly by App Engine
myapp/*.py: app-specific python code
views.py, models.py, tests.py, __init__.py, and more
templates/*.html: templates (or myapp/templates/*.html)
Here are some code examples that may help as well:
main.py
import wsgiref.handlers
from google.appengine.ext import webapp
from myapp.views import *
application = webapp.WSGIApplication([
('/', IndexHandler),
('/foo', FooHandler)
], debug=True)
def main():
wsgiref.handlers.CGIHandler().run(application)
myapp/views.py
import os
import datetime
import logging
import time
from google.appengine.api import urlfetch
from google.appengine.ext.webapp import template
from google.appengine.api import users
from google.appengine.ext import webapp
from models import *
class IndexHandler(webapp.RequestHandler):
def get(self):
date = "foo"
# Do some processing
template_values = {'data': data }
path = os.path.join(os.path.dirname(__file__) + '/../templates/', 'main.html')
self.response.out.write(template.render(path, template_values))
class FooHandler(webapp.RequestHandler):
def get(self):
#logging.debug("start of handler")
myapp/models.py
from google.appengine.ext import db
class SampleModel(db.Model):
I think this layout works great for new and relatively small to medium projects. For larger projects I would suggest breaking up the views and models to have their own sub-folders with something like:
Project lay-out
static/: static files; served directly by App Engine
js/*.js
images/*.gif|png|jpg
css/*.css
myapp/: app structure
models/*.py
views/*.py
tests/*.py
templates/*.html: templates
My usual layout looks something like this:
app.yaml
index.yaml
request.py - contains the basic WSGI app
lib
__init__.py - common functionality, including a request handler base class
controllers - contains all the handlers. request.yaml imports these.
templates
all the django templates, used by the controllers
model
all the datastore model classes
static
static files (css, images, etc). Mapped to /static by app.yaml
I can provide examples of what my app.yaml, request.py, lib/init.py, and sample controllers look like, if this isn't clear.
I implemented a google app engine boilerplate today and checked it on github. This is along the lines described by Nick Johnson above (who used to work for Google).
Follow this link gae-boilerplate
I think the first option is considered the best practice. And make the code folder your first package. The Rietveld project developed by Guido van Rossum is a very good model to learn from. Have a look at it: http://code.google.com/p/rietveld
With regard to Django 1.0, I suggest you start using the Django trunk code instead of the GAE built in django port. Again, have a look at how it's done in Rietveld.
I like webpy so I've adopted it as templating framework on Google App Engine.
My package folders are typically organized like this:
app.yaml
application.py
index.yaml
/app
/config
/controllers
/db
/lib
/models
/static
/docs
/images
/javascripts
/stylesheets
test/
utility/
views/
Here is an example.
I am not entirely up to date on the latest best practices, et cetera when it comes to code layout, but when I did my first GAE application, I used something along your second option, where the code and templates are next to eachother.
There was two reasons for this - one, it kept the code and template nearby, and secondly, I had the directory structure layout mimic that of the website - making it (for me) a bit easier too remember where everything was.