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 of reverse() to set LOGIN_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 in settings.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 use RequestContext in our views? Well, Context objects (noting that RequestContext is a subclass of Context) seem to almost entirely be used as arguments to a render() function, as demonstrated by “Rendering a context”.
    • But when you actually try to render a Template as returned by loader.get_template(template_name) with a RequestContext, which seems to be totally analogous to the examples in the documentation, the system throws a TypeError, claiming that “context must be a dict rather than RequestContext”!
    • This is because loader.get_template() returns an object of type django.template.backends.django.Template, not django.template.base.template (which is what that page actually discusses), because it’s using the DjangoTemplates backend, and this takes in a dict context, not a Context.
    • 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.
  • 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!)