Deployment or bust, part 2: Logging in and out
Picking up where the last devlog entry left off, we’re going to get logging in and out (i.e. sessions) working.
Jottings
- Use
reverse_lazy()
instead ofreverse()
to setLOGIN_URL
,LOGIN_REDIRECT_URL
etc. in the project-wide settings file.reverse()
won’t work because it relies on the project URLConf being loaded, which isn’t the case insettings.py
. - Easy-to-miss footgun in documentation regarding using auth-related variables
in templates. The “Authentication data in
templates”
section says that “the currently logged-in user and their permissions are
made available in the template context when you use
RequestContext
”. So do we need to explicitly useRequestContext
in our views? Well,Context
objects (noting thatRequestContext
is a subclass ofContext
) seem to almost entirely be used as arguments to arender()
function, as demonstrated by “Rendering a context”.- But when you actually try to render a
Template
as returned byloader.get_template(template_name)
with aRequestContext
, which seems to be totally analogous to the examples in the documentation, the system throws aTypeError
, claiming that “context must be a dict rather than RequestContext”! - This is because
loader.get_template()
returns an object of typedjango.template.backends.django.Template
, notdjango.template.base.template
(which is what that page actually discusses), because it’s using theDjangoTemplates
backend, and this takes in a dict context, not aContext
. - I believe the docs try to warn readers from making this mistake with the line “If you are using the DjangoTemplates backend, this probably isn’t the documentation you’re looking for”, but then they don’t point you to the documentation that a reader might be looking for…
- Whatever, just using the
render()
shortcut (like we were already doing) works in that we can include our (custom!) user fields in our templates just fine.
- But when you actually try to render a
- Links (i.e. <a> tags) always issue GET requests in HTTP (duh). If we
want a link that logs the user out (using the
LogoutView
), we need to issue a POST request, so we need a whole hidden form and restyle a submit button to look like a link. Kind of silly but eh.- HTMX solves this, but I’m not at the point where I’m sure including it would improve the project yet. Definitely considering it though, would simplify some AJAX stuff I’ve already written for task list CRUD.
Upshot
Logging in and out now works, and the four main views are inaccessible unless
you’re logged in, which is what we want. Next steps are making it so that it’s
impossible for a user who isn’t logged in to make any backend calls whatsoever,
i.e. add user authorisation to all views outside the main four, and sort out
permissions so that multiple users can be logged in and have their own private
views of their own private task lists. (We do this in Part
3.) I’m debating whether to get user registration
working and then just disable it when I deploy, or whether to pass and just use
accounts created via manage.py
for everything for now. (I’m leaning towards
the latter.) After all this I guess we can go through the Django deployment
preflight checklist, deploy, and finally cook some more actual functionality.
(Took me long enough!)