Django For Simplest Thing
Time to do some Simplest Thing development.
Technology architecture I'm aiming for:
- probably deploy on Heroku
- use straight Django (not Pinax)
- use standard SQL not MongoDb
- keep Data Model pretty simple: flat lists instead of hierarchies, etc.
- maybe use BootStrap for CSS work.
Mar09'2012now
Need to upgrade my Python to 2.7.2 (because Heroku document says I need 2.7x). (Python On Mac)
Ugh, now my PikiPiki won't run - urgh I know I've run into this in the past...
- root page is fine (that's not running Piki at all, but just the static stub server delivering
index.html
), but hitting actual PikiPiki script gives me a SaveAs dialog. Use C Url, find that it's trying to pass me the content of thepiki
script {{{ - Connected to localhost (127.0.0.1) port 8000 (#0)
GET /piki?BillSeitz HTTP/1.1 User-Agent: curl/7.19.7 (universal-apple-darwin10.0) libcurl/7.19.7 Open S S L/0.9.8l zlib/1.2.3 Host: localhost:8000 Accept: /
- HTTP 1.0, assume close after body < HTTP/1.0 200 OK < Server: SimpleHTTP/0.6 Python/2.7.2 < Date: Fri, 09 Mar 2012 16:39:57 GMT < Content-type: application/octet-stream < Content-Length: 17641 < Last-Modified: Fri, 15 Apr 2011 20:38:51 GMT < #!/usr/bin/python
"""Quick-quick implementation of Wiki Wiki Web in Python """ (rest of piki file) }}}
-
after some goofing around, suspect the issue is that I'm just using
piki
in the URL instead ofpiki.py
or that the script file itself is namedpiki
instead ofpiki.py
- nope, now it just delivers the script content without the SaveAs process.
- more precisely, I have 2 copies of the file, one named
piki
and onepiki.py
- if I just run
python piki.py
orpython piki
from command-line, it actually returns the rendered HTML ofFrontPage
! - if I ask for
/piki.py?BillSeitz
- by browser I get the plaintext of the script
- by
curl -v <http://localhost:8000/piki.py?BillSeitz
> I get {{{
-
Connected to localhost (127.0.0.1) port 8000 (#0)
GET /piki.py?BillSeitz HTTP/1.1 User-Agent: curl/7.19.7 (universal-apple-darwin10.0) libcurl/7.19.7 Open S S L/0.9.8l zlib/1.2.3 Host: localhost:8000 Accept: /
-
HTTP 1.0, assume close after body < HTTP/1.0 200 OK < Server: SimpleHTTP/0.6 Python/2.7.2 < Date: Fri, 09 Mar 2012 18:18:48 GMT < Content-type: text/plain < Content-Length: 17657 }}}
- if I ask for
/piki?BillSeitz
(which is what used to work)- by browser I get the SaveAs dialog
- by curl I get {{{
- if I ask for
-
Connected to localhost (127.0.0.1) port 8000 (#0)
GET /piki?BillSeitz HTTP/1.1 User-Agent: curl/7.19.7 (universal-apple-darwin10.0) libcurl/7.19.7 Open S S L/0.9.8l zlib/1.2.3 Host: localhost:8000 Accept: /
- HTTP 1.0, assume close after body < HTTP/1.0 200 OK < Server: SimpleHTTP/0.6 Python/2.7.2 < Date: Fri, 09 Mar 2012 18:22:11 GMT < Content-type: application/octet-stream < Content-Length: 17654 < Last-Modified: Fri, 09 Mar 2012 18:14:20 GMT }}}
- figure out that if I can change
pcgi.py
line tohandler_class.cgi_directories = ['/']
then it works! - unfortunately
SCRIPT_NAME
is now coming as//piki
which causes absolute-reference issues. Tweak that function to strip slashes then add back a single one. Now all good! (Not that I know what actually caused the change in behavior.)
Create VirtualEnv - argh, it's using Python 2.6 instead of 2.7.
- changed
$PATH
in bash_profile - next have to re-install virtualenv, etc. Still pointing at wrong place {{{
$ virtualenv st --distribute
New python executable in st/bin/python
Error [Errno 2] No such file or directory while executing command install_name_tool -change /System/Library/Fram.../Versions/2.6/Python @executable_path/../.Python st/bin/python
Could not call install_name_tool -- you must have Apple's development tools installed
Traceback (most recent call last):
File "/usr/local/bin/virtualenv", line 8, in
load_entry_point('virtualenv==1.7.1.2', 'console_scripts', 'virtualenv')() File "/Library/Python/2.6/site-packages/virtualenv.py", line 928, in main never_download=options.never_download) }}} sys.path
shows all 2.7 stuff
- (Mar10'2012) hmm, or maybe the real issue is the lack of install_name_tool. Per this I'm installing just the command-line-tools part of X Code, hoping I don't have to install the whole thing.
- of course there's no download of that piece available from Apple for my 10.6.x MacOs X.
- so I'm downloading the full X Code 3.2.6 for Snow Leopard.
- 2GB download, 10GB of disk space installed. Now successful.
- create virtualenv
st
, activate it. Installyolk
into it.
Now on to some actual Django handling
- tutorial uses project
mysite
and then apppolls
with model classesPoll
andChoice
pip install django
using docs https://docs.djangoproject.com/en/1.3/- verify that I have django v1.3.1
- freeze
pip freeze > requirements.txt
django-admin.py startproject mf
- I'm still at the/djcode/
level, so it createsmf
directory besidest
.- (went back and tweaked the
pcgi.py
for PikiPiki to use port 8001 since Django will default to 8000.) - go into directory, do
python manage.py runserver
seems good, hit URL, definitely good. Kill server - edit settings.py - add myself to
ADMINS
list, enter variousDATABASES
params forsqlite3
per my Sept15'2010 Django notes. Uncomment the adminINSTALLED_APPS
while I'm at it. - do
python manage.py syncdb
it creates tables, prompts me for Super User info, all good. - do
python manage.py startapp family
to make app - next: models
Some meta-notes on models
- here's the built-in model for
users
- I recall people recommending to me in the past to avoid exposing integer IDs to users/spiders. So should I aim to use UUID as ID?
- defining many-to-many relationships
- defining "choices" (selection-list) for a field's value. (Have to decide whether to associate text values with a key.)
Creating database schema from models
- edit
family/models.py
- edit
settings.py
to addfamily
to list ofINSTALLED_APPS
- do
python manage.py sql family
, get {{{ (in) class Family(models.Model): users = models.ManyToManyField(User) Name Error: name 'User' is not defined }}}- use command-line to enter SQLite, confirm that
auth_user
table exits (with my super-user record in it). Various examples seem to refer to this as classUser
. - ah, adding
from django.contrib.auth.models import User
up top solved this - notice that all the tables will get
family_
as a prefix. Is this what's supposed to happen, or is this a sign I'm running manage.py from the wrong directory or something? Yes this is normal behavior. So dopython manage.py syncdb
.
- use command-line to enter SQLite, confirm that
Trying admin interface
- uncomment lines in
urls.py
. Dopython manage.py runserver
, hit url http://localhost:8000/admin/ - all good
But in resolving a stupid mistake above, got alert that showed me I'm running Python 2.6 in here instead of 2.7!
- so, within virtualenv, just run
python
and see2.6.1
in the response block. - some links: 1 here here
- but decide I'm actually going to ignore this, since what really matters is that 2.7 is what gets installed on Heroku, not on my dev machine.
Mar12'2012
Use admin interface to enter some reference data (status codes, since will be dependent on task-type can't just use choices
)
Use admin interface to start entering some real master data (master Goals and tasks to pick from)
- find that by default
ForeignKey
field values can't be left as null- here's how to set Model to allow null
- have to use South to migrate data
- screwed up that setup process somehow. Finally fixed by using
reset south
method. Then got change made/migrated. (Also had to set default values for fields that I was changing to allow null, even though there were no actual records in that table.)
- screwed up that setup process somehow. Finally fixed by using
- (Mar13) can browse admin again, no data lost, all good.
- can add some tasks now
- tweak
__unicode__()
methods in a couple models to make admin record-lists more useful - next steps
- add some more reference projects/tasks
- add a few Resources
- start on user interface
Adding more tasks
- hmm, listing seems to show many records having a value that I thought I left null - is that the real data, or an issue with the
unicode
method? Need to sniff data directly.- cleaned up some data with command-line, but weirdness is definitely in admin-unicode listing, not the data.
- ah, if you refer to a
ForeignKey
in your unicode method, it gives you the entire unicode output of the linked record - that could get weird if you have a big hierarchy of records...
Done with some Tasks and Resources (Mar15).
Update some wireframes, esp of the user "dashboard".
Starting making a non-admin View following tutorial3, something isn't working.
So go back to tutorial2 on Admin Views.
Tweak field order/grouping for admin view of Tasks. Nice. (Mar25)
- find how to display a related-record-field in an admin list view
- never play with the admin templates or fancier views
Start on non-admin views (Apr03)
- enter 2 lines into
urls.py
likeurl(r'^tasks/$', 'tasks.views.index'),
and equiv for'tasks.views.detail'
- hit url
/tasks
, get 500 statusViewDoesNotExist at /tasks; Could not import tasks.views. Error was: No module named tasks.views
- hmm, could this be related to templates location? Go back to tutorial-2 to look at that bit.
- create directory
/djcode/mf/mytemplates/
- edit
settings.py
settingTEMPLATE_DIRS
to~/documents/djcode/mf/mytemplates
- copy
base_site.html
from/django/contrib/admin/templates/admin
to.../mytemplates/admin/
- hit
/admin/
url, not getViewDoesNotExist
error specific totasks.views
again!
- create directory
- another possible source of my confusion:
polls
in tutorial could refer to app or to 1 of its models! - so I add a couple url routes for
family
and hit url/family
- now I get theTried index in module family.views. Error was: 'module' object has no attribute 'index'
error expected from the tutorial.- of course, because
family
is both my app and 1 of my models, things are still confusing!- Actually, it's clear from the later bits of tutorial-3 that this is definitely the
app
name being referenced. What's confusing is how to handle urls and views from multiple models within an app. - And, scanning forward, discover that all this view work gets dumped with "generic views functions" in tutorial-4, but then after that you find out that in Django 1.3 they've changed to class-based generic views, for which there is no tutorial. Sigh.
- Actually, it's clear from the later bits of tutorial-3 that this is definitely the
- separate issue: do I want my urls to start with
family
,families
, orfamilys
? I guess I'll go withfamily
. - build
index.html
anddetail.html
views, all works fine so far - but can't get a listing-view from a model not tied by foreign-key to a single Family record. And no examples in the tutorial to help.
- Some non-tutorial info on queries is based around a WebLog app with
app=blog
and models ofBlog, Author, Entry
. But don't see that model carried over into Views, so it's not helpful. - The info on class-based Views uses yet another model:
app=books
, models ofPublisher, Book
.- then shows way of using
ListView
in urls.com and making a*_list.html
template to render it.- also note that using
extends "base.html"
means needing abase.html
wrapper template up beside the app directory at the top of the templates directory. - if this was a foreign-key related table, then I could display this sort of detail-list within the parent/related record using
DetailView
. Will get to that...
- also note that using
- now extend
task_list.html
template to link to the single-task detail view.... how?- tried wrapping item with
task.get_absolute_url
but that returned an empty string... ah, would need to define that method in the model - try
<a href="{% url task task.id %}">
- gotCaught No Reverse Match while rendering: Reverse for 'task' with arguments '(1,)' and keyword arguments '{}' not found.
- tried wrapping item with
- then shows way of using
- of course, because
Apr17: I'm getting tired of figuring out a framework. I want a mini/lite framework/library. I like writing SQL methods and stepping through dictionaries, etc. call me crazy. Gloria W says Pyramid "is the framework for people who hate Django", so I'll see if that feels better. Pyramid For Simplest Thing...
Edited: | Tweet this! | Search Twitter for discussion