Those who've been reading my older posts may remember I showed how you could
use Enum and IntEnum as a cleaner way to declare const-type values for choices
lists in Django fields.
That solution never felt comfortable to me, because Enum values aren't simple
values.
So after some playing around, and a brief look over the enum.py in python 3.5,
I've come up with the following:
Anyone who's been following my blog may have noticed it recently moved home,
and got a complete redesign.
This all happened because of my decisions to dogfood my own static site
generator.
A what, now?
Conventions, not Rules
As many newcomers to Python discover, a lot of things they've lived with as
rules in other languages [such as public/private members] ... and,
conversely, some things they're accustomed to as conventions are now rules
[like indenting].
Now, Django continues its history of embracing Pythonic ideals when it comes to
filenames. Many frameworks are very strict about what goes where ... in almost
all cases, Django couldn't care less.
Some years ago, I adapted the work of a coworker and released it as
django-classy-settings
, a way to define Django settings using a class,
allowing a clean and easy way to derive local / production settings from a
common base, and opening the way to allowing composition, too.
Recently I was faced with a similar problem at my current job, though not using
Django this time.
Another big difference is my current job is using Python3.6 (and eager to move
to 3.7 ASAP), opening other opportunities.
So, we've all needed a choices
list in Django at one time or another, right?
And from the docs we see the example code:
YEAR_IN_SCHOOL_CHOICES = (
('FR', 'Freshman'),
('SO', 'Sophomore'),
('JR', 'Junior'),
('SR', 'Senior'),
)
We've all had to write a search form at some point. Beyond simple cases, you
reach for the big guns, like haystack, et al.
But what about when it's just something simple? What if you want to, for
instance, let people search your blog posts?
In django, that can be done simply with:
Whilst working on my toy static site generator
gilbert, I decided I wanted it to use a
plugin pattern, so you could add new content types just by installing their
packages.
This would require some way for my code to automatically find all the related
packages, import them, and register their content type sub-classes.
But how?
Serialisers are increasingly important now that most web apps are just APIs for
the JavaScript to consume.
Serialisers help to reduce your living code objects into simpler types that can
be encoded in your serialisation format [typically JSON]. After all, JSON has
no date or time types, no classes, etc.
In the Django world, modern REST API libraries separate their Serialiser from
the views, and go to great lengths to make them easy to configure, simple to
use, and fast. They also support returning your "deflated" data into live code
objects.
So, I saw a post recently about Build an API under 30 lines of
code
using Flask.
I started wondering what it would take to do the same in Django.
The two main tools we're going go use are JsonResponse
and ModelForm
.
This comes up a lot in #django ... and the solution is [as many are with
Django] much simpler than people assume.
Frequently I see people reach for formsets, in the mistaken conclusion that
formsets are for operating on related models. The sad part is that formsets
rely on the same functionality that the proper solution relies on, but the
seeker does not see it.
Somewhere people get the idea that for a single <form> submission, they
can only use a single Form class... but the formset should show that that's not
true; it uses multiple forms from the one submission.
Django provides many decorators for use throughout your project. They can be
great time savers, and mastering them can help you DRY your code considerable.
However, they often confuse people as to how they work, or how to write their
own.
In this post I plan to walk through an example of building up a simple
decorator that tests if the user has a specific permission, and if not
returning a 403 Forbidden response.
Decorator basics.