Live data from Hacker News

Some more things about Django I've been enjoying

jvns.ca

31–40 of 128 posts

Re: Some more things about Django I've been enjoying

#31
post #21
post #6

The Django filter syntax with the double underscores is like fingernails on a chalkboard to me. I find it insane that they didn't just use operator overloading to create a real query expression language.

There may be many reason other than rejecting that suggestion leading to what it is know. Your statement somehow suggests that it was deliberately decided against what you propose. I don't think we know that. I can't quite picture how operator overloading would look like, could you give an example?

You might want to look at Peewee's query filtering syntax.

https://docs.peewee-orm.com/en/latest/peewee/querying.html#f...

Re: Some more things about Django I've been enjoying

#32
post #24

Earlier quoted context omitted.

if self._midnight(today) returns a datetime object, than: self.filter(end__gt=self._midnight(today)) will evaluate to: self.filter(end__gt= ) While self.filter(Field.end > self._midnight(today)) will evaluate to: self.filter( )

Not if you do the magic with getattr and comparison overrides. You actually need to do it on the metaclass because the Field as I wrote it isn't an instance but this works: from datetime import datetime class Filter(): def __init__(self, name): self.name = name def __gt__(self, value): return { "field": self.name, "operator": ">", "value": value } class FieldMeta(type): def __getattr__(cls, name): return Filter(name)…

If you change an operation that is meant to return a Boolean to return anything else, you are insta fired.

Re: Some more things about Django I've been enjoying

#33
Do not use the development http server in a production setting. Use gunicorn or some equivalent.

I had the same issue with incredibly low throughput on beefy machines and it's because the dev server implementation is single threaded and does not do concurrency at all.

Switch to gunicorn.

Re: Some more things about Django I've been enjoying

#34
post #32

Earlier quoted context omitted.

Not if you do the magic with getattr and comparison overrides. You actually need to do it on the metaclass because the Field as I wrote it isn't an instance but this works: from datetime import datetime class Filter(): def __init__(self, name): self.name = name def __gt__(self, value): return { "field": self.name, "operator": ">", "value": value } class FieldMeta(type): def __getattr__(cls, name): return Filter(name)…

If you change an operation that is meant to return a Boolean to return anything else, you are insta fired.

You mean like the numpy authors that let the comparison operators return arrays?

Also, apparently SQLAlchemy does exactly what I proposed so apparently they are erring in their ways too.

I honestly don’t find it that bad.

Re: Some more things about Django I've been enjoying

#35
For Django's default template language, does it still have these limitations?

1. Brackets aren't allowed to help with boolean expressions like {% if a and (b or c) %}

2. You can't do basic arithmetic like {{ x * 2 }}, but you're allowed to do {{ x | add:"2" }}. There's hacks to multiply using {% widthratio a 1 b %} or division with {% widthratio a b 1 %} though (https://stackoverflow.com/questions/18350630/multiplication-...).

3. You can't assign expressions to variables like {% with x = a or b %}, so you have to repeat yourself.

4. You can't capture HTML generated from template code in a variable to pass into a partial template to write slots-style HTML components e.g. {% capture x %}Hello {{ username }}{% endcapture %}{{ include "partials/header.html" with body_html=x }}.

5. You can't pass variables to model methods.

I understand there's a philosophy that templates shouldn't contain complex logic, but I find the above pretty arbitrary and leads to code that's harder to maintain. Addition is okay but not multiplication? Boolean logic is okay but not with brackets? I often have to puzzle out some way to get my code to work that goes against what I'd normally want to do, some I'm forced to duplicate template code because you can't put expressions in variables or move basic one-off logic into views (which has poor locality https://htmx.org/essays/locality-of-behaviour/ and makes it harder to move template snippets between pages).

It's like hiding the kitchen knives because they might be misused.

Is Jinja2 a practical alternative or there's friction to using it?

Re: Some more things about Django I've been enjoying

#36

Do not use the development http server in a production setting. Use gunicorn or some equivalent. I had the same issue with incredibly low throughput on beefy machines and it's because the dev server implementation is single threaded and does not do concurrency at all. Switch to gunicorn.

Better yet, put gunicorn behind nginx, make sure all static assets are served by nginx, add appropriate Cache Control headers. Furthermore understand and use Django’s page caching.

Re: Some more things about Django I've been enjoying

#37
post #32

Earlier quoted context omitted.

Not if you do the magic with getattr and comparison overrides. You actually need to do it on the metaclass because the Field as I wrote it isn't an instance but this works: from datetime import datetime class Filter(): def __init__(self, name): self.name = name def __gt__(self, value): return { "field": self.name, "operator": ">", "value": value } class FieldMeta(type): def __getattr__(cls, name): return Filter(name)…

If you change an operation that is meant to return a Boolean to return anything else, you are insta fired.

I would have agreed with this, and then they did the `pathlib.Path` bit of cuteness with the `/` operator: https://github.com/python/cpython/blob/5afbb60e0283caaf34990...

And despite my misgivings, it’s really ergonomic.

Re: Some more things about Django I've been enjoying

#38

> Some light load testing (with (ab -n 1000 -c 1) shows that right now we can serve about 2-3 requests per second (on a ~$10/month VM). > After turning on template caching, it seems like the site can now pretty easily handle 12 requests per second or so without using all of the CPU. I have not carefully benchmarked the before and after but it seems like it’s made a pretty big difference. That seems crazy low, I think…

Yeah... in the place I worked, for a while, they didn't have a package index for Python packages (similar to PyPI), so, I wanted to write one. At the time I had a love-hate relationship with Ada, so, after trying to do something with Python and thinking how much resources I would have to ask for and whether I'll need load balancing etc... I checked what Ada's (somewhat unfortunately named AWS...) would need to be used as that kind of index. Suffices to say that I wouldn't need any of the "reverse proxy" servers, no caching, no load-balancers... It would be fast enough to service a company with thousands of employees on a very modest h/w setup.

Using Django is like trying to walk on a highway, with a crutch. Even though it has some convenience features, it's just so impossibly slow you would have to invest a lot of engineering time and resources to mitigate that slowness.

Re: Some more things about Django I've been enjoying

#39

For Django's default template language, does it still have these limitations? 1. Brackets aren't allowed to help with boolean expressions like {% if a and (b or c) %} 2. You can't do basic arithmetic like {{ x * 2 }}, but you're allowed to do {{ x | add:"2" }}. There's hacks to multiply using {% widthratio a 1 b %} or division with {% widthratio a b 1 %} though ( https://stackoverflow.com/questions/18350630/multiplic…

> Is Jinja2 a practical alternative or there's friction to using it?

jinja2 is drop in by changing the template backend. You can actually run both at the same time (just can't mix them, ofc).

https://docs.djangoproject.com/en/6.0/topics/templates/

Re: Some more things about Django I've been enjoying

#40
post #9

I have been using Django since 0.95 and I haven't seen anything which is so flexible with amazing DSLs while also making it easy to understand the magic behind it. For the last 10 years, even in a Golang stack or Java stack, I still use Django for models and migration. I even have generators which generate Gorm (or other framework) DAO or Java hibernate classes using Django models. With LLMs, it becomes easier since…

> I still use Django for models and migration

There are dozens of us! It's a great db management toolkit. I've used it to much success many times for things like managing migrations from mysql to postgres and php to python.

My opinions:

- Django apps are an anitipattern for large internal / single purpose products due to migration overhead as FKs cross application boundaries. I will die on this hill. No team is ever disciplined enough to keep apps as boundaries for relationships and constraints. Strong contrast to the rails crowd that doesn't rely on referential integrity in the db by default where this isn't "a thing".

- Goose[0] migrations in Go are really great but you have to let go of the dsl and the idea that your ORM drives your migrations, as you explicitly called out. Laravel[1] is on par with django IMO and a delight to use when in php-land. I've not tried to repurpose it like I have with Django and sqlalchemy.

- sqlalchemy and alembic is a great toolchain outside of django that get's a bit of a bad wrap / confusion from django devs. it gives you that same ability to drive the changes from the classes / structs without having to drag around all of django. It having more verbose

[0] https://github.com/pressly/goose

[1] https://laravel.com/docs/13.x/migrations

Post reply on HN