5 ms·
> 1. There's a bunch of things a I disagree with in here. Can you share?
by valbaca 5y ago
> 1. There's a bunch of things a I disagree with in here.
Can you share?
- travisjungroth 5y agoThe core thing is that I haven't been a fan of the services layer described here. I'm more of the opinion that if you're going to use Django, use it all the way. Fat models and all that. But, when I read more thoroughly, the guide makes a really compelling case. I've generally scoffed at the idea that you shouldn't couple your business logic to Django in case you want to swap out Django for something else. It's hard to imagine a realistic situation where that doesn't lead to a total rewrite anyway. But putting business logic in functions for readability and testability makes sense to me. Other disagreements flow from that same one. Not testing your models much being an obvious one. Not a fan of Hungarian notation. I've had a better experience with type hinting than the author. I don't share the disdain for URL parameters. From my first quick skim, that felt like a lot. But I really do agree with much more in this than I disagree with (one big app to start, small serializers, good function calls, unique names and lots more). And the things I do disagree with, this guide has me reconsidering (except type hinting. I love that shit). I mostly wanted to point out that even if I don't agree with everything written there, I think it's very well written.
- mands 5y agoI've gone back and forth on fat models vs service issues myself - I've landed on a bit of both in the end, but it's made harder by DRF not really recommending the fat model approach (with respect to validation).
- travisjungroth 5y agoIsn't it amazing we're still all poking around how to best represent business logic in software when this has been the whole damn point of what we're doing for the last 30 years at least? We got pretty good at the pure computing stuff pretty quick, but like hell we can all agree on how to represent that a food purchase over $100 by a user in Wyoming needs a 5% tax added.
- Daishiman 5y agoThe problem is that different levels of granularity imply enormous differences in representation. If you operate in a single jurisdiction and sell just a coupld of SKUs, handling tax can be a 20-line affair. On the other end you have SAP multi-million line ERPs that handle tax as far as the eye can see and you need literal specialists just for that.
- lifeisstillgood 5y agoYes. That has touched on something deeply important. I wish i knew what :-) My 2c is "software literacy". We live in a literate world so we all more or less can read the sentence "food purchase over $100 by a user in Wyoming needs a 5% tax added." and understand it. But 98% of people could not scan the same in C, C++, Python etc. And 98% of those of us that could wont understand the context the code sits in (whats the variable name 'WY_TAX_PCAGE'?)
- mdtusz 5y agoI think your comment emphasises the importance of good function and variable naming. I've read some incredibly clear and obvious C code and some incredibly hard to understand Python code that both do the same thing - it basically all comes down to the naming choices used. `TAX_RATE_WY` would be far easier to understand and maintain (especially when seeing other state abbreviation suffixes nearby) and has the added benefit of using the same `TAX_RATE_` prefix for _all_ similar values so is much easier to pick up on when scanning through the code. The science of reading and literacy would likely be a very valuable course to teach in CS programs.
- kimsia 5y agoHow many times can I upvote this about software literacy?
- mands 5y agoYep, it feels like a corollary to bike-shedding, the business logic case, but I think you've described it better than me!
- danjac 5y agoI generally use "services" when there's a glob of logic that works with a number of models and other things. For example, you might have some order checkout logic that has to write to a number of database tables, send email and other notifications, and ping a third party service or two. You don't want to tie all that logic to a single model as it crosses a number of boundaries, and you don't necessarily want it inside a view, as it might be run in some other context such as the command line, or perhaps run from different views. On the other hand, if there is logic that is neatly encapsulated within a model instance or queryset, I don't see a good reason to artificially make a service for it. Generally refactoring into services is something I do when it's obvious what their responsibilities and boundaries are.
- daveungerer 5y ago> you don't necessarily want it inside a view For the Rails developers like me who are thinking the Django crowd have lost their minds for even considering such a thing (and who went straight to the comments instead of reading the article), I just learnt that Django views are roughly equivalent to Rails controllers. Source: https://docs.djangoproject.com/en/dev/faq/general/#django-appears-to-be-a-mvc-framework-but-you-call-the-controller-the-view-and-the-view-the-template-how-come-you-don-t-use-the-standard-names https://docs.djangoproject.com/en/dev/faq/general/#django-ap...
- mands 5y agoYes this is a good compromise and something I do also - services for cross-model business logic that can be called from multiple entry points, e.g. views, admin, management command, celery tasks, etc.
- dd82 5y agoJames Bennet is of the same opinion as you re service layers https://www.b-list.org/weblog/2020/mar/16/no-service/ https://www.b-list.org/weblog/2020/mar/16/no-service/ https://www.b-list.org/weblog/2020/mar/23/still-no-service/ https://www.b-list.org/weblog/2020/mar/23/still-no-service/
- po 5y agoI'm founder/CTO of a successful SaaS company with 10+ years of code evolution in the same Django codebase. I tried and tried for years to make fat models/model managers work. I feel like it just doesn't work. It's just not composable enough. You can't reuse business logic in web views, forms, admin views, API, background processing, etc... time and time again the Django tooling gets you 90% of the way there, then leaves you with no way to do what you need done cleanly so you one-off an ugly solution to it. Soon you code is littered with them. We ended up with a solution much like this article and despite it being a bit of a pain it always works in all contexts.
- neilfrndes 5y agoGreat to see validation from someone who's used Django for a decade! Curious about how you transitioned from the fat model architecture to services based in the same codebase? Did you use some sort of versioning?
- deleted 5y ago[deleted]
- deleted 5y ago[deleted]
- deleted 5y ago[deleted]
- maxmorlocke 5y agoAs a startup CTO and heavy django user, I'd agree with the general assessment - there are some things I don't like stylistically... but that's style. Everything in here is well reasoned and systematically covered. Kudos to you and your team for thinking this through and sharing it. As an example of some nitpicks: * I never interact with the raw request data, I pass that through to a form or serializer for validation. It handles the null/blank string based on my configuration. In fairness to your approach, your code is much more readable and will be substantially easier for someone who is new to Django to pick up. * I use mixins to handle fat models, while also pushing validation logic into serializers. * I separate out all my files and prefer to have small, atomic files that are easily testable (e.g. models, views, etc. are all micro-sized files). * args/kwargs is super handy when doing something really simple, then calling super. I feel like this is an exception that should always be allowed, but otherwise strongly agree. * I bias towards class use, even though I agree there's no real need. I find this to be a good convenience for new developers coming aboard. I want to reiterate that I feel like these are nitpicks / minor disagreements of compromises. Using a document like this as a guidepost is awesome for a new team kickstarting with Django - better to have a reasonable, well thought out set of rules codified than to have a whole hodgepodge of design decisions.
- mtberatwork 5y agoOn the point of classes and functions, it doesn't specifically address "function based views" and "class based views" of Django - it's mostly a tirade on OOP in Python. The majority of the Django world has long switched to class based views.