Notes from learning and experimenting with django.
Assumptions, Environment, Etc
All of the following assumes you’ve setup python like:
- Python version is 3.11.0
- Using a virtual env via
python3.11 -m venv <dir>
And are using django
4.1.
MVC
Models are as expected and via django.db.models.Model
. django Models
Controllers in the django world are really the django views. django views are created via one of a few template systems and “Forms”. The django docs say “Django has the concept of “views” to encapsulate the logic responsible for processing a user’s request and for returning the response.” which sounds like a traditional controller to me.
I’m not webapp aware enough to know the subtleties here, but I think that’s right.
How To Restrict Model Access?
The builtin django authentication system has a concept of permissions. A bunch of examples use manual checking of permissions, but it looks like there’s a nice PermissionRequiredMixin
helper that makes sure a user requesting a view has permissions for a list of models.
Although I’m not sure how that works if the user can only view a subset of model objects? EG if there’s a global “Runs” table how does it only allow a user to see their runs?
Model Managers: custom QuerySet
I think this might be a nice way of doing this. Create a custom Model
manager that takes a User
for construction, and only returns rows the user has access to in the QuerySet
.
Customization
The page on customizing django has a lot of useful tidbits. Reading through, it peels back some of the layers and shows how the django people think.
It also calls out django foot-guns. For instance, they suggest creating a custom User
class out the gate (even if it’s just a no-op class) because changing the User
class after the initial migration is a pain.
Models
Internal Customization
The Meta
class can be used to tweak a bunch of internal Model knobs. I came across this when trying to make the display names in the admin interface more useful (by default, they just use <ModelName>
which means the admin view for a model type isn’t very useful.
Unfortunately it doesn’t work for this use case because the class Meta
is used by the Model
meta class during creation of the Model
class, not during creations of Model
instances. It turns out that just adding a __str__
to your model works!