|
Let's say you're following the approach of breaking down your project into separate apps, so you have an app called user_accounts. This app would be a folder containing files like: views.py, services.py, models.py, test_views.py
So in views.py you'd have a User class, with: A POST method that calls services.create_user(username, email_address, password)
A GET method that calls services.get_user_profile(request.user)
A PUT method that calls services.update_user_profile(x, y, z)
A DELETE method that calls services.inactivate_user(request.user)
The return value of each of these views can just be whatever services.get_user_profile(request.user) returns, rendered into JSON.Then each of the services performs whatever business logic it needs to, preferably directly in the method. But if it would be more readable split into multiple methods, then you can create some private helper methods in the services file prefixed with an underscore. You can also have a separate folder somewhere for utility functions meant to be reused across the app, e.g. get_user_emails(request.user, is_active=True, is_verified=True) Basically though each view sanitizes the data, e.g. strips XSS out of strings, makes sure booleans are actually booleans, etc. Then each service first does field-level validation with serializers, e.g. ensuring that usernames meet the appropriate requirements for usernames. Next if there is other business logic validation that needs to happen, it happens, e.g. making sure that only users with verified email addresses can perform certain actions. After that you perform the actual business logic, e.g. transforming any data. Then you perform your CRUD operation, e.g. creating a user model. And lastly you return something, e.g. returning the user model. Each endpoint and service method can be written pretty much following this pattern, which makes the codebase super readable because once you understand one endpoint you understand all of them. And the service methods are the reusable component of the architecture, so e.g. if you want the ability for admins to create users, then they are created with the exact same service method. (But called from your admin endpoints/services.) |
It also resembles very much what I see in Java projects which use DDD (Domain Driven Design).
What's your take on the article's point that you should have fewer rather than more Django apps (citing the problem of inter-app-FKs)?