Hacker News new | ask | show | jobs
by andrewstuart 1055 days ago
I've done extensive development with Flask, Bottle, Django, Falcon, Django Rest Framework, Starlette, Sanic and FastAPI over about 13 years or so.

These days I prefer to build my back end applications with nodejs, TypeScript and plain SQL (no ORM) talking to Postgres.

I like Django but it pissed me off no end that it's called "batteries included", except that the very first thing you need to do with any Django project is going and find some batteries for the user signup auth flow. That's not batteries included, and its not something you should need to figure out for yourself in a batteries included framework. It's time consuming, complex and error prone and should be built in.

Anyhow as I say, I've prefer nodejs though I still do use Python for lots of stuff.

3 comments

> I like Django but it pissed me off no end that it's called "batteries included"

The fact that the Django project and you have different preferences and consider different things essential is not a failure on their end. The fact that this "pisses you off" seems to indicate that you could channel your passion into more productive paths.

That doesn't make sense. Django-allauth is the standard for non-rest Auth flow, django-rest-auth and djoser for rest API Auth flow. Each implementation is tailored for a slightly different case.

There's a reason why only admin views are kind of built in and if you want you can expose admin to the end user and it supports the entire Auth flow out of the box.

I can't seem to be able to edit from mobile, I'm actually not sure if you can create a user using /admin out of the box. Anyway, it's a MTVC framework. Views and templates are coupled, and Django provides a user registration form if you want. Of course no one uses that since big projects are using Django for its orm and only need the rest API. The 2 libs I mentioned above are easy to plug in, but they rely on drf, so in order to battery-include the feature you want, Django would have to merge with drf first.
Batteries included means the stuff you need for most uses is already included.

The fact that there are many possible add ins to solve this doesn't address the fact that Django does not include core functionality for web applications.

You mentioned running nodejs + typescript over extensive frameworks like django now. Curious if you chose to write your own framework or are you using something from nodejs space to do "batteries included" thing for you?

Asking because I've had some experience with nest.js and even though it's fun it often feels hackish and a bit messy even when solving standard issues like authorization that's not a simple app wide RBAC.

I don't really know what is different.

I can say that nodejs and TypeScript and pure SQL is so simple and straightforward that I seem to need almost nothing in terms of "framework". I just write endpoints with a query behind them.

On reflection I spent alot of development time hacking around in Django models/forms and the ORM and really almost none of that is needed if you just write straight SQL with Postgres. It's just unnecessary complexity - once you cut all that guff out then things start to become REALLY simple. Request/auth/query/response.

I put auth into a separate web application which gets called by Caddy (or you coudl use Nginx) as an auth subrequest. This makes auth extremely easy, and gives a very powerful decoupling and separation of concerns.

For many years I have thought, finally, that's the last time I need to write a user signup/forgot password/signin flow, but every project still seems to need it written, so I do that myself.

This approach of super simple, just talking to Postgres also would work well with Python but I have come to really like TypeScript more than Python. The latest Python projects I wrote were pretty much Starlette with asynpg talking to Postgres and no ORM or other fluff - that's a pretty nice combination, and asyncpg is the fastest Postgres driver for Python by a country mile which is also nice.

If I wanted RBAC then I would intercept all my SQL queries and wrap them in Postgres RBAC environment variables that implement the Postgres constraints. I've done this before with Django, it worked pretty well, but I think it would be nicer and cleaner in a system without ORM or database abstraction of any form.

I don't understand how what you're describing is batteries included where Django isn't?

It's typically not practical to solve "auth flows" in a centralized way -- needs are so different for different projects. There are tons of third party modules you can just plug in...

My batteries included comment related to Django, nothing else.
Personally, Next.js with NextAuth and Prisma for ORM is a much better full stack dev experience for me. Django templates are their own DSL, adding JS is more annoying and less powerful to do than React/JSX, Django Auth is cumbersome, Django Rest Framework will immediately feel like an old Java EE OOP way of doing REST or JSON API...
The built-in auth system is one of the things I dislike the most about Django.

It's 2023, people log in with e-mail addresses, and even if they log in with a username, make it case insensitive ffs

The very first thing I have to do with each project is completely rebuild the user system, and if you wait until later then it's too late and it's way more difficult to do (according to the docs themselves)

Yep.

The moment you install Django, you have to add all the auth stuff to your todo list. If you're not a Django expert then its easily hours or days pointless work.

Pretty frustrating to instantly be given the large and for some people intimidating problem of implement signup/signin/forgot password/reset password and do it all properly, reliably and securely, even whilst Django smugly asserts that it's "batteries included".

You have to head off and find which auth plug in system to use, work out what is still maintained, which provides the features you need and then the task of integrating it with whatever front end you need to present to the user. All this you need to do if you are new to Django.

It's a huge gap in the Django offering, and makes Django look pretty out of date.

Django should come with a built in user flow that allows signup/signin/forgot password/reset password as well as related emails, and it should come with support for json web token and cookie session, plus example UI code for React, VueJS, plain HTML and maybe some of the other common JavaScript front ends too, as well as APIs for other front ends to use.

Why they don't provide this is hard to understand. It's just instant makework for developers.

Either this or drop the "batteries included" thing.