3 ms·
> Does any one have a good overview on how the community actually separates functionality into “apps”? For the most part there isn't any need to, with the exce
by Alex3917 8y ago
> Does any one have a good overview on how the community actually separates functionality into “apps”?
For the most part there isn't any need to, with the exception of things explicitly meant to be shared. So if you are a large company and want a bunch of custom auth logic or something to be shared among many different teams running their own Django service, then you might want to build that as an app. Or else if you were building something as an open source project you might want to do the same.
In terms of separating apps by functionality, I think the main reason many people do it is because they are under the mistaken impression that putting things into different apps will make them magically re-usable. That's not to say you shouldn't do it, only that I think most people do it for the wrong reasons.
In general I would say don't bother splitting up your project into different apps by functionality until you have too many models to comfortably fit into one file. That might not be until 20KLOC. For apps that are less than 10KLOC, I think in most cases the overhead probably outweighs the benefits.
There isn't really any hard rule one how to do this, but you might do something like:
- Account management app for creating and deleting users, getting user profiles, password resets, etc.
- Apps for integrations with third-party APIs, e.g. Duns or Mailgun.
- Apps for different front doors, e.g. if you make a Facebook chat bot that's powered by the same tech that powers your normal website.
And then after that you can possibly split up your business logic of your core website into different logical components, but I would do that last. By the time you get there you should start to have a feel for how to do this.
The one place I use it for our own startup is that we recently built a couple different front doors for our site, and each one accepts data in a slightly different format and has different authentication requirements. I put each of these in their own apps, but everything else is just in one main app.
- hrayr 8y ago> until you have too many models to comfortably fit into one file. That might not be until 20KLOC. Even for larger apps in my django project, I convert my models into a package and split all my models into individual files (same with views and serializers for DRF). This keeps my models easier to manage.
- mattrp 8y agoApps can be a good way to generalize a set of classes for reuse in other projects. For instance we put auth into an app so if we fire up other projects we don’t have to rewrite auth.
- digitaltrees 8y agoThanks for the thoughtful response. Do you find yourself repeating code, or struggling to decide where code should live and where it should be imported?
- Alex3917 8y agoI had this problem for the first couple years, but not anymore. What I did: - I split the core app up into different views and services based on the functionality. For FWD:Everyone this is basically: account_management, admin_apis, content_discovery, organizations, upload_thread, read_thread, comments, and user. I have a folder for all my views and a folder for all my services, and for each view there is one (or occasionally two) service files. So e.g. in the views folder there is a file called account_management_views, and then in the services folder there is a file called account_management_service. For utilities that get re-used across the entire app I have two additional things in the services folder, one is called util.py and the other is io_util.py. Util is for things like sanitizing XSS that don't require any database access, and io_util is for things like get_user_from_username, get_user_from_email_address, etc. Then you can import any models into io_util.py, but never into util.py. And you can import anything from util.py into io_util.py, but never the other way around. Then you can import anything from either util or io_util into any service method and shouldn't have any issues. (Although I always just import util or io_util, and then call the methods like util.sanitize_xss.) Once I structured the services and utilities that way I never had issues again with circular imports or figuring out where to put stuff. Importing with Python is kind of difficult and janky in general, but so far this pattern seems to be working pretty well for both our startup and also for the consulting projects I've done. Basically for logic that's mostly specific to a single view, put it in the services file for that view. Public functions in that folder can still be re-used in other services, but if they're fairly generic and they're re-used in more than one or two places then consider moving them into util or io_util so as to avoid circular import issues.