Django Notes

0 comments

A few tips, tricks, gotcha's, and other findings from working with Django for Python.

Complex Queries

Complex queries are run in Django as "raw" queries. The following information will get you well on your way with complex queries including queries on databases other than the default in a multi-database setup.


  • Multiple databases require Django 1.2+
  • When performing raw queries, the table and column names are the actual names define in the database, not the names modeled in Django.
  • Raw query must include the primary key
  • Use db_manager('mydb') to specify other than the default database.
    Ex: Author.objects.db_manager('mydb').raw('SELECT id, name FROM library_authors WHERE ....')
  • Use cursor for even more complex queries. These can be handled by a class to simplify accessing.
  • Use 2 %'s (%%) when using % in a raw query.
    Ex: "LIKE %foo" ~~> "LIKE %%foo"

References

https://docs.djangoproject.com/en/dev/topics/db/multi-db/#using-raw-cursors-with-multiple-databases
https://docs.djangoproject.com/en/1.3/topics/db/sql/
http://osdir.com/ml/django-users/2010-01/msg01419.html
http://www.djangobook.com/en/2.0/chapter10/
https://docs.djangoproject.com/en/dev/topics/db/queries/#escaping-percent-signs-and-underscores-in-like-statements

Note the warning about passing parameters to raw,
https://docs.djangoproject.com/en/dev/topics/db/sql/#passing-parameters-into-raw

Modeling Existing Tables

When modeling existing tables by default, Django gives each model an "id" field. This can cause an unknown column error if your table does not have an id field. Resolve this by declaring another column as the primary_key.

see:
https://docs.djangoproject.com/en/dev/topics/db/models/#automatic-primary-key-fields

Passing Data to a Template

Troubleshooting

Caught OperationalError while rendering: (1054, "Unknown column 'myTable.id' in 'field list'")

https://docs.djangoproject.com/en/dev/topics/db/models/#automatic-primary-key-fields
must assign a column as primary key so Django does not try to use default 'id'