Why I use Django services layer

One question that is often asked on Django reddit is "Where do I put my business logic?". There are a few possible answers to that:

  • The "official" one: Models (fat model approach)
  • Managers and QuerySets
  • Services

I do think that, unless you're build a strictly CRUD app, neither of the 2 first approaches are good enough.

Most of the products and apps I've been building are pretty "complex" in the sense that they can't work alone. I mean, they need to handle multiple writes to the database, connect to external systems (usually via REST APIs) and do lots of business checks (multiple models).

For me, I doesn't look as if I could put these things in any of the previous 2 items. Hence, the "service layer".

I always end up creating a services.py file where I write methods that do all those things. Not uncommon to a method, still trying to keep the single responsibility principle, do a sequence of things that are related: read a model, check conditions, connect to an external API and so on.

One application we are building is for a logistics center. This kind of application, usually, have lots of business checks. You have to check product availability, product lot expiry dates, communicate with internal and external ERPs etc.

These operations must be done in sequence and, sometimes, in a idempotent manner. In these cases, I can use the @transaction decorator to guarantee that.

There some good points delineared here and I think, from the discussions I've seen and participated, that Django community is leaning towards to the non-services approach. My guess is, since Django is an "old" framework (17 years "on the road") and, in its inception the fat model approach was a thing for building sites and CMSs, it doesn't take into account the kind of business logic I mentioned above.

I tend to keep my models and views very thin. Services comes to help me centralize the business logic (remember, Separation of Concerns) separated from my data and my presentation.