Live data from Hacker News

Django Styleguide

github.com

121–130 of 141 posts

Re: Django Styleguide

#121
post #113

Earlier quoted context omitted.

Are you aware of https://ccbv.co.uk/ ? After I discovered that, class based views became easy.

And if you're using DRF there's https://www.cdrf.co/

Wow, 8 years of using Django and I did not know about either of these. Thanks!

Re: Django Styleguide

#122

Earlier quoted context omitted.

How is that adding an ORM to the ORM? I want all django orm access to happen at defined places, instead of the spaghetti mess it is when people do SomeOtherModulesModel.objects.filter(..) and expose themselves to the internal workings of that module. Access it through a selector instead.

An orm takes a selector (typically an sql query) and maps it onto an object. What you're describing takes a selector, and maps it onto an object. Is it just that you want type hints or something?

No, what I'm describing is functions in a selector.py, like: def get_orders_for_date(date) -> Order:

where Order is a pydantic model, not a fat django model. Other modules shouldn't know about my internal database. All other modules should use functions from this selector.py, they aren't allowed to use the OrderModel themselves directly, only the pydantic class. Because otherwise you end up with spaghetti.

Re: Django Styleguide

#123

Earlier quoted context omitted.

How is that adding an ORM to the ORM? I want all django orm access to happen at defined places, instead of the spaghetti mess it is when people do SomeOtherModulesModel.objects.filter(..) and expose themselves to the internal workings of that module. Access it through a selector instead.

If for some strange reason your application has data that it was not created with Django, sure. But aside from that you are just adding another layer of abstraction that does not give any benefit when all your models are managed by Django already.

It gives a huge benefit, and not doing it is why most django code is incomprehensible and slow.

No longer should anyone in their module directly do something to a model and save it. They should always go through a service in the module owning that model, that makes sure everything is done correctly. So services.py and selectors.py works as a public API for the module, while the models are internal. Avoids having lots of other apps/modules depending on your app's internals.

Re: Django Styleguide

#124
post #84

Earlier quoted context omitted.

This is good enough to break circular dependencies between individual modules, but keep in mind that circular dependencies between the apps remain (e.g. job depends on mediator, mediator depends on job). I usually prefer to resolve those too. If job is small enough, all the orchestration of jobs should happen through mediator (same for load). If it's not plausible, then job can emit signals which mediator subscribes…

> ...all the orchestration of jobs should happen through mediator (same for load) So, in a smaller app, when a request comes into job/views.py or load/views.py then we immediately start working with JobLoadMediator to handle business logic between the two? I was just going to focus on specific tasks between job and load. I'll probably look into signals; I haven't used those in several years and as I recall, it felt h…

Although it goes against certain opinions AND if you set a norm for their use, signals are the way to go.

You can either decide that signals code will live in the app where the objects reside or the app of the target objects and that's it. A built-in and simple interface between objects.

Re: Django Styleguide

#125
post #99

Earlier quoted context omitted.

> when a request comes into job/views.py or load/views.py then we immediately start working with JobLoadMediator to handle business logic between the two? In my world, mediator.views and job.views would likely have different audiences. mediator.views is for business domain (e.g. your API). Though name would not be mediator, it would be something domain-specific. job.views could be for more low-level internal tooling…

> mediator.views is for business domain (e.g. your API) > job.views could be for more low-level internal tooling That's very interesting. I'm mostly following the architecture from: https://phalt.github.io/django-api-domains/styleguide/ I knew this was going to be a large project, about 19 apps, supporting a trucking and inventory web/mobile app, and I wanted a sane/organized way to deal with all of the models and re…

If you try to keep everything in one app, you'll have gigantic views.py, models.py, etc.

Nobody wants to work with those. Also, a simple typo in those files can bring your whole system down and can make it hard to debug.

Apps, are a cheap (EXCEPT when you HAVE TO [but really, do you? Really?] move models between apps) way to keep YOU sane.

Re: Django Styleguide

#126
post #84

Earlier quoted context omitted.

This is good enough to break circular dependencies between individual modules, but keep in mind that circular dependencies between the apps remain (e.g. job depends on mediator, mediator depends on job). I usually prefer to resolve those too. If job is small enough, all the orchestration of jobs should happen through mediator (same for load). If it's not plausible, then job can emit signals which mediator subscribes…

Holy bovine. This finally worked. I've been working around the clock on this for two days now. Thanks again stranger!

Also, do not forget to integrate with Sentry [https://sentry.io/] or something that does the same thing.

It will also keep you sane.

Re: Django Styleguide

#127
post #18

Earlier quoted context omitted.

It's a pet peeve more than anything - I just hate it when I have to scroll around to find if a class is abstract or not, our team puts it at the top so that's never an issue. Having it anywhere else means it can be any arbitrary number of lines below the class definition making it harder to find.

I’ve never worked on a Django codebase that puts Meta at the top of a model definition. Not saying that it’s the wrong hint to do, but this just feels like feigned surprise because you surely also know that it’s far from common.

It very much was feigned surprise, though I do know a few Django devs who prefer top. I've never really understood the logic for hiding it in the middle or at the bottom even though both are much more common.

Re: Django Styleguide

#128

Earlier quoted context omitted.

If for some strange reason your application has data that it was not created with Django, sure. But aside from that you are just adding another layer of abstraction that does not give any benefit when all your models are managed by Django already.

It gives a huge benefit, and not doing it is why most django code is incomprehensible and slow. No longer should anyone in their module directly do something to a model and save it. They should always go through a service in the module owning that model, that makes sure everything is done correctly. So services.py and selectors.py works as a public API for the module, while the models are internal. Avoids having lots…

> not doing it is why most django code is incomprehensible and slow.

> No longer should anyone in their module

> they should always go through a service

Weasel words and opinions-as-fact. Come back when you have a way to show that your approach gives any actual benefit.

Re: Django Styleguide

#129

Earlier quoted context omitted.

An orm takes a selector (typically an sql query) and maps it onto an object. What you're describing takes a selector, and maps it onto an object. Is it just that you want type hints or something?

No, what I'm describing is functions in a selector.py, like: def get_orders_for_date(date) -> Order: where Order is a pydantic model, not a fat django model. Other modules shouldn't know about my internal database. All other modules should use functions from this selector.py, they aren't allowed to use the OrderModel themselves directly, only the pydantic class. Because otherwise you end up with spaghetti.

Right... so you're talking about mapping an object from your database to a pydantic object.

So you want an ORM, but you want it without a save method? Or presumably with a save method that can only be called under specific circumstances?

Re: Django Styleguide

#130

Earlier quoted context omitted.

It gives a huge benefit, and not doing it is why most django code is incomprehensible and slow. No longer should anyone in their module directly do something to a model and save it. They should always go through a service in the module owning that model, that makes sure everything is done correctly. So services.py and selectors.py works as a public API for the module, while the models are internal. Avoids having lots…

> not doing it is why most django code is incomprehensible and slow. > No longer should anyone in their module > they should always go through a service Weasel words and opinions-as-fact. Come back when you have a way to show that your approach gives any actual benefit.

I did give an example. What you call opinions-as-fact was me trying to explain the approach, not commanding anything. That you disagree (or can't comprehend it?) doesn't make it weasel words. Please don't behave like this towards me, read the guidelines. You can find a link at the bottom of this page. I'll leave this "discussion" here as it's unfruitful when you act so hostile.
Post reply on HN