3 ms·
> Always keep your models slim. As simple as possible, but no simpler. Django models are meant to deal not just with the data, but also with business logic. If
by rglullis 4y ago
> Always keep your models slim.
As simple as possible, but no simpler. Django models are meant to deal not just with the data, but also with business logic. If `course.has_finished` is a property of the course, why would you want to have a separate function outside of the class?
> Do precomputation if you need the information in a template
If the precomputation is only needed in a template, you can (should, IMO) use template tags.
> Don't make separate apps in the same project (...) avoid dependency hell.
My current pattern here has been to create one "core" project where I represent all the internal models of the domain of the application, and "adapter" apps if I want to interface/integrate with anything from the external world. This makes it easier to extend or replace third-party tools.
> (Migrations) It's built around a fragile model.
I wouldn't call it fragile, quite the opposite. There are some annoying limitations for sure (I didn't find a reliable way to change the primary key of a model, except for creating a whole new model and migrating the data to it), but I think they are due to a matter of strong safety that the migration can only be done if it consistent.
- well1912 4y agoAt my current company, we've had many teams over the years fail to make business logic in model methods work, and I think many other people have had similar results. The issues usually boil down to some combination of "business logic is too coupled to the data model" and "this method lives at an intersection of these two models and creates weird dependency problems". I now feel that Django puts you down a path for failure by naming the DB layer "models" and not giving users a decent place to put cross-model domain logic. My current preference is a functional core-imperative shell-style architecture where as much code lives in the functional core as possible. It's not very elegant with Django but it works fine. Cosmic Python (really accessible and fairly quick read if you have the time: https://www.cosmicpython.com/book/preface.html https://www.cosmicpython.com/book/preface.html) has examples that are similar.
- rglullis 4y ago> The issues usually boil down to some combination of "business logic is too coupled to the data model" and "this method lives at an intersection of these two models and creates weird dependency problems". Refactor is not a dirty word. The problems you are describing seem to be more of the nature of having too many things concentrated at specific model classes, and that this model should be decomposed, broken down. This is not a Django-specific issue.
- lowercased 4y ago> I now feel that Django puts you down a path for failure by naming the DB layer "models" and not giving users a decent place to put cross-model domain logic. I think a lot of 'MVC-inspired' frameworks fail there, not just django. Rails... 'app/helpers' maybe? Laravel 'models' is it, and 'services' or a variation is something I see a lot of folks adding, but it's not an out of the box convention. I can't remember anything specific/explicit in the asp.net world either.
- matsemann 4y ago> If `course.has_finished` is a property of the course, why would you want to have a separate function outside of the class? Because one should avoid passing Django models around. It leads to bad design. Have a selector or something that uses the ORM, but exposes some dataclass or pydantic model instead, and put the logic there.
- traverseda 4y agoYou want to add an ORM to the ORM? Why?
- matsemann 4y agoHow 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.
- rglullis 4y agoIf 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.
- matsemann 4y agoIt 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.
- 4y ago