| > 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. |
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) has examples that are similar.