Django reusable apps and namespace - python

My team is starting a new Django project.
We want to start using git submodules in our new project. We've used submodules in previous projects and it worked great for us. The idea is to have apps, that we regularly use in projects, in a common folder as a git submodule.
Assume our git location is at git#mygit.git:repo-django
We have the apps (repo-django) in the root of the project like so:
/myproject
repo-django/
app1/
models.py
app2/
models.py
app3/
models.py
There is some debate in the team around how to structure the packages and I can't find any guides on what would be considered the best option in this regard.
Should "repo-django" be added as a class path so that imports of the modules can be relative to the root of repo-django or should repo-django form part of the class paths?
To use the models for example:
from repo-django.app1.models import MyModel
we can add the app to django like so:
INSTALLED_APPS += (
'repo-django.app1',
'repo-django.app2',
'repo-django.app3',
)
or if we add repo-django via:
sys.path.append("repo-django")
Then we can use the models like so
from app1.models import MyModel
...and add the apps to django like so:
INSTALLED_APPS += (
'app1',
'app2',
'app3',
)
The big debate is around namespaces. One camp argues that putting all the reusable apps in namespaces is a good thing while the other camp argues that the apps will be less portable and too dependant on the folder name.
What would be the best approach and where can I find more information on this?

Related

In Django, how is the term "app" defined?

In my Django app, I have a lot of code so I have split up my source files and put them into sub-folders, as follows:
myproject/
myapp/
management/
__init__.py
models/
__init__.py
common.py
users.py
matches.py
questionnaires/
demographics/
templates/
__init__.py
models.py
views.py
...
views/
__init__.py
abstract.py
concrete.py
Now I'm confused what to put in INSTALLED_APPS. Is it all the folders containing models? Or all the folders containing source? If i include all child folders, do I also need to include the parent folder? Should this match what's in my my setup.py's packages argument?
Note: I know I could refactor this into multiple apps, but (1) I would like for all this functionality to have a common namespace since it's being redistributed and (2) I am regardless curious for the answer to my question.
Put the directory containing the models.py file, that is your "App". Django uses the models to bind to the database, everything after that is just filler.
The DJango startup is (very slimmed down) as such
manage.py
# The important part
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "path.to.your.settings")
This will define the important pieces, but lets look at the installed
settings.py
INSTALLED_APPS=(
'your.app.name'
)
Which basically states, you'll find my models.py there and some model definitions (they don't have to be defined, but models.py needs to exist)
your/app/name/models.py
class SomeModel(models.Model):
#... model definition ...
pass
Now back to your settings.py
Your source can live ANYWHERE because DJango looks in some very specific locations for certain things, but this is mostly configured in your settings.py
ROOT_URLCONF = 'path.to.urls' # this is the pythonic module path to your `urls.py` file
in your urls.py file you can define a url such as
url(r'^/some/url/def/$', 'some.other.module.handler'),
as long as handler from some.other.module returns a valid HttpResponse object and is on the PYTHONPATH it does not matter where the class lives.
Django has some specifics about management commands, they must live inside your app directory (the same as your model dir) so to define those (if your model.py file is inside a different location) you must put them in your data dir
For example I have a project with the following layout
/app
/data
/commands
some_command.py
models.py
/app
urls.py
settings.py
...other-source-files...
My settings.py simple says load the app data and point to app.url for the url configuration, from that point on it doesn't matter where your source lives (for the most part).
We did this so that our database tables would be named data_sometablename vs app_sometablename (i was not part of this choice, happened long before i joined)

Where should I place models.py in Django?

This question makes in part reference to Django directory structure? .
How should I place the models.py in Django?
Project_name/
Application1/
models.py
Application2/
models.py
or
Project_name/
DB/
models.py
Which one should I use? why?
Daniel Roseman is correct, when running manage.py startapp appname, Django will automatically create a directory structure with a separate models.py per app like:
appname/
models.py
As well as being convention (if other Django developers come to look at your code, this is where they will expect to find your models) it also allows people to create reusable apps
e.g. by simply copying the appname directory I have all the URL patterns (if any), views, models, forms, tests and everything else, rather than having to pull out all the files from a large separate directory.
The first option is correct in Django each app has her own models.py or models directory.

Importing models in Django python

How can I import all models in the settings.py in INSTALLED_APPS? When i`m trying to insert some model there is an error occurred: "no models named app1_model"
-ProjectName
--ProjectName
---models
----__init__.py
----admin.py
----app_1_model
----....
----app_n_model
---templates
---__init__.py
---settings.py
---urls.py
---wsgi.py
--manage.py
^ Structure of project ^
The INSTALLED_APPS is for apps not for models. Models are classes that live within your app, usually in /«app_name»/models.py.
I think you have misunderstood how a Django project is structured. Try working through a tutorial example.
a typical structure:
/«project»/«app_name»/models.py
and in settings:
INSTALLED_APPS = [ ... '«app_name»' ... ]
Your path will contain the base project directory, so you can import your app where you need it.
And to use them:
from «app_name».models import *
Although it is always best not to import *, instead, name the classes you wish to import.
To answer the question in the comment:
If you don't like the idea of storing all your models in one file (even though it is normal to do this), you can create a module called models. To do this, create a directory called /«project»/«app_name»/models, inside it put __init__.py (to declare it as a module) and then create your files inside there. You then need to import your file contents into the module in __init__.py. You should read about Python modules to understand this.
To answer the second comment question:
To view models in admin, you should create an admin file with model admin objects.
And finally:
Please read through the tutorials to ensure you have a thorough understanding of Django. Otherwise you're wasting your own time!

Custom Tags in Django 1.2 with Google App Engine Python 2.7

Creating a custom tag in Google App Engine Python2.5 with Webapp used to be a joyful experience. Here: Django templates and variable attributes
But now, in Python 2.7 with Webapp2 and Django 1.2, it is a pain in the ass. I can only find bits of information here and there, and some of the methods contradict with each other.
The method described in http://www.john-smith.me/Tag/webapp2 ranks high in Google, but some people claim it is "what a waste of time" Webapp2 custom tags
This one method seems to work
from django.template.loader import add_to_builtins
add_to_builtins('xxxxx')
But I dont know the details. Who can provide a step by step example?
I dont know why there are no official documents about these stuff. I mean, this is not science experiments in which we explore the unknown. There supposed to be some documentation so the developers can save their time.
I had same problem.
The fix:
Create templatetags folder. Add there module with custom tags as explained in Django docs Custom template tags and filters.
Example folder structure:
app.yaml
myapp/
__init__.py
templatetags/
__init__.py
my_tags.py
In settings.py set INSTALLED_APPS to myapp (name of folder which contains templatetags sub-folder):
INSTALLED_APPS = ( 'myapp' )
Now when you call {% load my_tags %} in template Django should also seek the mytags module in myapp/*/templatetags/ folder.

Project structure for Google App Engine

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.

Categories

Resources