Top
Best
New

Posted by brylie 3/29/2025

Plain – a web framework for building products with Python(plainframework.com)
310 points | 160 commentspage 2
askonomm 3/29/2025|
First thing that I don't like is the settings being strings that reference classes. Usually that means that go-to definition does not work (I've seen similar things in Symfony with YAML use). If the config needs to reference a class, or some object, I would like to be able to easily navigate to it as opposed to having to manually search the project for it. If this was an actual object reference as opposed to a string, I could, and I'd also get intellisense for if I typed it right or not, and autocomplete.

Then of course they "solve" it later with a (probably paid) plugin. But why? LSP's support this natively, and for free, just don't use strings.

mdaniel 3/29/2025||
There are strings in Python already that reference classes: type annotations. PyCharm knows how to populate, warn, and navigate to the "interior" types there

I can't think of any reason why it couldn't be taught to behave similarly for a config file. You can do it today field by field via language injection but if there are a lot of them then I think the config file would need a JSON Schema with the x-intellij-language annotations on the relevant fields https://sourcegraph.com/github.com/JetBrains/intellij-commun...

beaugunderson 3/29/2025||
> First thing that I don't like is the settings being strings that reference classes.

Those classes can reference the settings, so including them as strings is done to allow that to work without creating circular imports.

askonomm 3/29/2025||
Ah yeah, didn't remember that constraint in Python. I thought I read something about a future version fixing that when it comes to just type hints, but I suppose that wouldn't work here, since it's not really a type hint, right?
beaugunderson 3/29/2025||
Yup, you're thinking of "postponed evaluation of annotations", which is currently optional with `from __future__ import annotations`. But as you said, would not fix the circular import here.
mcdirty 3/29/2025||
Tbh why should I use this over Django? Less docs and knowledge around it. Less maintainers. Idk seems like a business risk to invest real time in it for me
daft_pink 3/29/2025||
I think to really learn Python for web as a developer you really have to learn WSGI/Gunicorn/etc and handling sessions within this.

I’ve found the challenge with Python for web is deployment as most website deployments are geared towards serverless workers or cdn’d javascript bundles and most python systems use WSGI and sessions, which is fundamentally different and the biggest challenge in newbie’s using python for websites.

dplgk 4/5/2025|
If you're building your own framework and server, then yes. Otherwise, all major frameworks handle the communication with uwsgi, etc and you can treat them as a blackbox. Any other setup in-between (like nginx -> uwsgi) is boilerplate stuff easily found in tutorials or LLM chat.
mychael 3/29/2025||
Where is the unique value add? It's like the only differentiation is that they ran sed 's/django/plain/g' across the repo.
brokegrammer 3/29/2025|
One immediate value add for me is built-in structured logging: https://plainframework.com/docs/plain/plain/logs/README.md

Setting this up in Django requires some gymnastics.

jgb1984 3/29/2025||
Yeah, no thanks, I'll stick with Django (my bread and butter for over 15 years now!).
scottpersinger 3/29/2025||
you lost me at "fork of django". Start with FastAPI and work up from there, and borrow good ideas from more modern frameworks.
librasteve 3/29/2025||
This feels right and wrong at the same time.

It’s right (as explained in the about):

- to like Django and all the 1000s of contributions

- to be frustrated by its limits & to want to do more

- to fork and rearchitect if you can’t get there by debate

- that people may like it and come along or the ride

- in many of the features and design points

- to embrace HTMX

It’s wrong:

- to try to innovate on the Python/Django ecosystem

- to miss out on functional code for HTML composition

- to continue the framework paradigm - HTMX leads to server side which leads to devs reclaiming the application loop

If, like me, you feel that plain is on the right track, but want to go faster / further, then I encourage you to take a look at https://harcstack.org. [disclaimer, I am the author]

barrenko 3/29/2025||
Do you have more posts about this? My main gripe about Django is that the usual html templating options are but-uggly (as opposed to those that ship with Rails), but I haven't tried one of the new options.
m000 3/29/2025|||
I wish django's template engine was demoted to a contrib package and eventually replaced by jinja (i.e. jinja becoming a django dependency).

I understand that django templates started with the intention of eliminating programing logic in the templates (presentation). But the implementation of the concept is very puritanistic, to the point of becoming counter-productive. Jinja's approach OTOH is less opinionated: you can be a puritan and emulate django's approach if you want, but you can also be less dogmatic about the logic/presentation separation if that serves you.

As someone very aptly put it on reddit [1]:

> Jinja may let program logic layer bleed into the presentation layer, but with Django it seems there's no way to do it without presentation layer bleeding into program logic layer.

[1] https://www.reddit.com/r/django/comments/13n9pfd/is_it_me_or...

librasteve 3/29/2025|||
thanks for your interest … I have this to whet you appetite

https://rakujourney.wordpress.com/2024/10/27/raku-htmlfuncti...

i’m planning a series of posts on HARC stack starting tomorrow (just finalizing first one)

you can use the RSS at https://raku.org or subscribe to https://rakudoweekly.blog/ to get them

BoorishBears 3/30/2025||
And immediate and persistent 502 is not a great endorsement.
librasteve 3/31/2025||
eating own dog food and I made an error - red face
scop 3/29/2025||
This looks cool. FWIW I’m not a Django guy, but pulled up the site (djangoproject.com) out of curiosity to compare it to Plain. One thing that stood out to me was this:

> Ridiculously fast.

> Django was designed to help developers take applications from concept to completion as quickly as possible.

This rubs me as a little deceptive/insincere. When I read “ridiculously fast” on a hero banner, I’m expecting that to mean the speed of the language/framework itself. Anybody else see it similarly or am I just being cranky?

Anyways, I as an outsider see a lot more immediate value proposition on the Plain page than the Django one. Good job whomever put it together.

pphysch 3/29/2025||
I use Django at $DAYJOB for multiple projects and love it but definitely see its age. I would never migrate to something "slightly different" like this.

I have a different approach to "modernizing Django", which is to write a spiritual successor ORM from scratch, which is Postgres-only and be "closer to the metal" while maintaining a porcelain Python API. Sounds insane, but "just use Postgres" is real and it already has a number of killer features that aren't possible in (core) Django due to its complexity and commitment to a standard SQL abstraction.

fud101 3/29/2025|
interested in this approach. do you get task queues for free? what else?
pphysch 3/30/2025||
- a much more Pythonic control flow than Django: there's no big settings.py file that does a bunch of magic. "Management commands" are just regular python scripts that get executed within your apps context. Can run in Jupyter notebooks. Much less OOP and framework complexity overall.

- task queues via LISTEN; NOTIFY; SELECT FOR UPDATE;, which builds off the above. Your worker processes don't have to load the entire app, just the parts it needs.

- fully typed using the latest generic type support

- first class support for dropping to raw SQL, the ORM isn't trying to reinvent everything Postgres can do. Mostly waiting for PEP 750 before finishing this feature.

- even more JSON field support, including a subclass called "Attributes" that exposes declared keys as Python attributes. CHECK JSONschema support via a Postgres extension.

- RLS integration, including a "tenant" context manager so you can do `with transaction(tenant_id="foobar"):` and all queries run in the block will be constrained by what that tenant can access according to RLS policies defined on each model. Mainly a first line of defence, but adventurous devs could give tenants read-only SQL access to their tenant data (e.g. for an analytics service).

- a Model base class called "Entity" which uses UUIDv7 for PKs and implements many powerful features, like generic FKs, soft-deleting, changelogs

- model-level support for JSON de/ser, so you don't need a separate DRF

- not trying to reinvent a WSGI/ASGI web framework, instead it tries to integrate nicely with starlette or whatever with some session support.

- migrations, postgis, maybe bitemporal fields, and so on

sgammon 3/29/2025|
By what metric is Python the most popular language on earth? I'm actually curious, genuinely asking. I thought JavaScript (Node) was king of newly written code, but perhaps that is outdated information.
simonw 3/29/2025||
https://github.blog/news-insights/octoverse/octoverse-2024/ - "In 2024, Python overtook JavaScript as the most popular language on GitHub, while Jupyter Notebooks skyrocketed—both of which underscore the surge in data science and machine learning on GitHub."

What's missing here though is TypeScript: I believe if you combine JavaScript and TypeScript together they still beat Python on GitHub.

sgammon 3/29/2025||
Thanks, this is interesting. I'm also a big fan of your blog posts :)
globular-toast 3/29/2025||
It is number one according to the most widely cited index: https://www.tiobe.com/tiobe-index/ So if you want the actual metrics and methodology you'd have to go there.
More comments...