In an ideal world, each app would be independent of the others, or only loosely coupled to the others. But in many real world situations, there are often so interdependencies that it's hardly worth trying to abstract them.
So, then, in that case.. the best way to separate them is to divide them into functional groups where the majority of the views, models etc in each app are used solely within the app. So, given your github example, the "issues" could be their own app. The issues
app would have specific views that are related solely to displaying, editing and serving (ajax requests, etc) issues, models for storing issues and their ongoing status, templates which are solely responsible for rendering issue views, issue entry for example, issues per user, issues per project, details of a particular issues. There's actually a lot of issue-specific code.
And yes, by the time you're done, you'll have for example foreign keys from those issue models to user models and to perhaps a commit model, a project model.. many interdependencies that would prevent the issues
app from working without the presence of other apps. But logically, when it's time to work on the issue system, you'll know where to go.. because all the issue code is in one place. All the default issue settings are in issues/settings.py
for example, all the tables primarily related to issues will be prefixed with the app_label
eg. issues_issue
, issues_comment
.. etc..
So basically, try to break it up on the basis of core functionality, and minimize the number of dependencies.. or at least, try to avoid circular dependencies.. eg, some apps will have many other apps depending upon them, some will have none. Try to avoid a deadly embrace. But, in the end, dependencies will happen.
In some cases, you may be able to implement optional dependencies, eg.. when something happens in App A, Model_A, it should trigger something happening in App B, Model_B.. but only if App B is installed. There are ways to do this less-closely-coupled behavior, such as Django's signal system
https://docs.djangoproject.com/en/2.0/ref/signals/
But this is not as reliable as a foreign key, so do not go out of your way to loosely couple things which will never be uncoupled.
Try to divide things into apps on the basis of closely coupled functionality, eg. views that are related to other views. Put things which all your apps rely upon into your master app or into a library.. and you'll find that your code is much easier to maintain as it grows.