How to divide a django project into applications - django

I want to know how to divide a project having a hierarchical structure into applications. Let's say that I'm trying to build something like github.com.
In github.com, an account has some repositories, which have some features like code, issues, or pull requests. And those features have references to other features. In this case, which is an application and which is not? At that time, should I put applications in the root directory or in an application directory as sub-applications?

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.

I would put the applications at the level of your manage.py file in your main project, then you can easily run this command: python manage.py startapp login_app. Then you can have a structure like so:
main_project
login_app
codeissues_app
pullrequests_app

It's not possible to create independent apps for every app in your project. I suggest you to follow the domain driven design. (google it)
So imagine you are building a ecommerce shop. You would have something like:
your_project_folder
docs
readme
static
your_project
domain # here you put the models logic
cart
products
payment
shipping
tax
infrastructure # your packages to interface with other services
paypal
stripe
interface
rest
another_rest
presentation
public_site
...
This is just an example of how you can divide the project. Than you must have boundaries. In the domain folder you must group the packages (and so design your model) to not permit cross references.
Interface, Infrastructure and Presentation can access to the Domain.
The Domain should be more stricter. Have a look here: https://martinfowler.com/bliki/BoundedContext.html
Anyway this is just the surface of the subject. Depends a lot of what kind of project you are building and what are the requirements. Have a look at the Domain Driven Design.

Related

Django project-apps: What's your approach about implementing a real database scheme?

I've read articles and posts about what a project and an app is for Django, and basically end up using the typical example of Pool and Users, however a real program generally use a complex relational database, therefore its design gravitates around this RDB; and the eternal conflict raises once again about: which ones to consider an application and which one to consider components of that application?
Let's take as an example this RDB (courtesy of Visual Paradigm):
I could consider the whole set as an application or to consider every entity as an application, the outlook looks gray. The only thing I'm sure is about this:
$ django-admin startproject movie_rental
So I wish to learn from the expertise of all of you: What approach (not necessarily those mentioned before) would you use to create applications based on this RDB for a Django project?
Thanks in advance.
PS1: MORE DETAILS RELATED ABOUT MY REQUEST
When programming something I follow this steps:
Understand the context what you are going to program about,
Identify the main actors and objects in this context,
If needed, make an UML diagram,
Design a solid-relational-database diagram, (solid=constraints, triggers, procedures, etc.)
Create the relational database,
Start coding... suffer and enjoy
When I learn something new I hope they follow these same steps to understand where they want to go with their actions.
When reading articles and posts (and viewing videos), almost all of them omit the steps 1 to 5 (because they choose simple demo apps), and when programming they take the easy route, and don't show other situations or the many supposed features that Django offers (reusability, pluggability, etc).
When doing this request, I wish to know what criteria is used for experienced programmers in Django to determine what applications to create based on this sample RDB diagram.
With the (2) answers obtained so far, "application" for...
brandonris1 is about features/services
Jeff Hui is about implementing entities of a DB
James Bennett is about every action on a object, he likes doing a lot of apps
Conclusion so far: Django application is a personal creed.
My initial request was about creating applications, but as models are mentioned, I have this another question: is with a legacy relational database (as showed in the picture) possible to create a Django project with multiple apps? this is because in every Django demo project showed, every app created has a model with their own tables, giving the impression that tables do not interact with those of other applications.
I hope my request is more clear. Thanks again for your help.
It seems you are trying to decide between building a single monolithic application vs microservices. Both approaches have their pros and cons.
For example, a single monolithic application is a good solution if you have a small amount of support resources and do not need to be able to develop new features in fast sprints across the different areas of the application (i.e. Film Management Features vs Staff Management Features)
One major downside to large monolithic applications is that eventually their feature sets grow too large and with each new feature, you have a significant amount of regression testing which will need to be done to ensure there aren't any negative repercussions in other areas of the application.
Your other option is to go with a microservice strategy. In this case, you would divide these entities amongst a series of smaller services and provide them each methods to integrate/communicate with each other (APIs).
Example:
- Film Service
- Customer Service
- Staff Service
The benefits of this approach is it allows you to separate capabilities and features by specific service areas thus reducing risk and regression testing across the application when new features are deployed or there is a catastrophic issue (i.e. DB goes down).
The downside to this approach is that under true microservice architecture, all resources are separated therefore you need to have unique resources (ie Databases, servers) for each service thus increasing your operating cost.
Either of these options is a good option but is totally dependent on your support model and expected volumes. Hope this helps.
ADDITIONAL DETAIL:
After reading through your additional details, since this DB already exists and my assumption is that you cannot migrate it, you still have the same choice as to whether or not you follow a monolithic application or a microservices architecture.
For both approaches, you would need to connect your django webapp the the specific DB you are already using. I can't speak for every connector out there but I know that the MySQL connector allows django to read from the pre-existing db to systematically generate the models.py file for the application. As a part of that connector, there is a model variable which allows you to define whether or not Django is responsible for actually managing the DB tables themselves.
The only thing this changes from an architecture perspective is how many times do you want to code this connection?
If you only want to do it once and completely comply with the DRY method, you can build a monolithic application knowing that as new features become required, application wide regression testing will be an absolute requirement.
If you want ultimate flexibility for future changes with this collection of features and don't mind recoding the migration across multiple apps while reducing the need for application wide regression testing as new features become required, a microservice architecture strategy is more appropriate.

DJango Models & Apps

Good afternoon,
I am new to Django and having trouble conceptualizing how to lay out some of my apps in a project. I get the obvious apps for "ActivityTracking" & "GameStats"
Where I am struggling is the glue that ties all of this together - the Person. I was helped yesterday on importing the Person model into apps to use a Foreign Key of the models (Using DJango Models across Apps) but I am struggling at where to put my PersonModel (what app?)
There are three scenarios in my app. The AppAdmin who will create / delete / import / move between departments of users (among other items of overall administration such as onboarding data sources). A particular user will be able to manage his own Person object to update information and see his/her own statistics, and a team leader will be able to see his departments performance.
Where would this Person model go to appropriately be positioned for these three use cases?
Sorry if I am not asking this well, but I am having a hard to conceptualizing where to place this central piece of the overall application.
Thank you for your insight.
EDIT: Basically the crux of my question is: Is it considered OK in "The Way of Django" to have an app that has no views, URLs, or templates, its sole purpose to have a model that is utilized by the other apps?
Thank you!
Let me start with this description from Django documentation:
The term application describes a Python package that provides some set of features. Applications may be reused in various projects.
Applications include some combination of models, views, templates, template tags, static files, URLs, middleware, etc. They’re generally wired into projects with the INSTALLED_APPS setting and optionally with other mechanisms such as URLconfs, the MIDDLEWARE setting, or template inheritance.
As you can see, Django's app is defined here as a package that provides some set of features.
The implication here is that those features are semantically, conceptually and physically separated (physically meaning operating on different classes) so that they can be naturally decoupled. This is the goal you should be aiming for when designing your architecture.
Example: In a generic e-shopping portal you will have some kind of Account and Product. Then it is natural to divide views into apps accounts and shop (for example), where accounts is reponsible for managing user-related information and shop for manipulating product-related information. Both apps have separate urls, models, views, etc.
However, clean separation may not be always possible. In your case, as I understand it, the core object is Person. Moreover, all three use-cases operate on Person. Based on this information one might assume that those views are related and should be placed in a single app. Of course, there are no go-to solutions here and you have to trade-off between a lot of things. For example, how many views are you going to write? 10 views are fine for one file (views.py) but in case of 100 I would consider splitting them into multiple files (if not apps). On the other hand, it's way more convienent to keep models close to views that import them.
One common practice is to maintain app named common for all handy things. However, I never had to hold my mission-critical models in it and I would not recommend it.
Is it considered OK in "The Way of Django" to have an app that has no views, URLs, or templates, its sole purpose to have a model that is utilized by the other apps?
It's fine if there is really good reason for it, but I would be very suspicious of bad architecture. That's a red flag for me.
All in all I would classify your three use-cases in the following way:
The AppAdmin who will create / delete / import / move between departments of users (among other items of overall administration such as onboarding data sources).
That's management or accounts. This app defines Person model - it's semantically consistent.
A particular user will be able to manage his own Person object to update information
That's in management/accounts too.
[...] and see his/her own statistics, and a team leader will be able to see his departments performance.
Those two belong in something like statistics. This app imports Person from management.

Django Web Application Design Guidance

I am looking for some advice before I start on a new project.
I am creating a Web Application using Django 1.10. I have experience with Django and creating general "content-based" websites with it. However, since this project is going to be a web-based application, I plan on doing more "complex" things than just rendering HTML templates and doing some basic CRUD operations. When I say "complex" things, the most specific example I can give at this point is to leverage more asynchronous requests so my web-application can remain responsive to the user and provide that "real-time" experience that comes with an application that might be installed on their local machine or whatever. Plus, since this is a web-application and not just a website, the project is definitely going to be more data-driven which could potentially mean requesting large amounts of data that would be best served in say a paginated manner, etc.
So, my though was this.....Since I am familiar with Django and have read such good things about the Django REST Framework, I could create a RESTful API to perform all of my CRUD operations and basically interface with my web application's core database.
At that point, I could essentially have two "layers": (1) A presentation layer that will render my web-application's pages and (2) an application layer that will do all my backend CRUD operations. Since the two are separated, I will also get the added benefit of being able to leverage the API from other avenues (other than my Django web-app) if that is ever required down the road.
I guess my first question is whether or not this makes sense and if so, thoughts on the best way to implement it. I believe I have two options.
Create a single Django project and include the API as a separate application. This seems like it would work fine but it would couple my API with my presentation since they would both be hosted by the same server. Which...if the only "consumer" of the API is my one Django site, then this may not be an issue in the near term but could cause problems later on.
Separate the two into two distinct Django projects. This offers the most flexibility and is probably the best answer, I think.
There may be other options as well. At the end of the day, I am looking for some advice/guidance from those who have done this before and what other things I should consider before starting on this effort.
Basically I would not recommend the way number 2. This is because you really fast will start to struggle with issues like that: where to store models? Project A, Project B, Both?? Also I am almost sure that you will have other code that can be shared between both of the django projects.
Worth to note here that in two separate django projects - you will have troubles with synchronization of the migrations (just consider simultaneously change of the models in both projects). Personally - I've never was able to solve this in some nice, acceptable way.
Maybe I will share with you my personal experience - hope this will be helpful.
First is that if your are making a big application - consider resignation from django templates - use some modern js framework for frontend: react, angular; and make a separate project for fontend. This is tricky because you need to have right competences in the team. If this is not possible - well do separate django app for front.
Use DRF - you can create rest app inside your project and use all of the models defined elsewhere - it will provide you simple CRUD out of the box and with some work it can be really powerful. If you will be able to create front in modern js framework - this REST can be also used to feed data to the front. And also any other client you can imagine. This basically shift the amount of work needed to be done in the backend (only REST instead of REST + templates and rendering) to the frontend.
Asynchronous tasks. Well nothing new here - use celery. Define your tasks inside application; make sure that you have correct number of workers. And let the magic begin.
As for real-time experience, you may consider using django-channels: https://github.com/django/channels/ It is nice way to handle websocket connections.
Things to consideration:
In big application usually you will end up with something like this:
myapp.com -> point to frontend; api.myapp.com -> point to the api
You should make a clear separation in the code between this two. In the case when your front is js-based - this is not a problem, but rest + rendering it is important to be able to run only-api-node and only-rendering-node. It's hard to say which one of them will be used more heavily.
So basically you can end up with something like this:
core
models
users.py
my_app_frontend
users
views.py
forms.py
tasks.py
urls.py
my_app_rest
users
serializers.py
views.py
signals.py
urls.py
my_app
settings.py
rest_settings.py
manage.py
wsgi.py
rest_wsgi.py
urls.py
rest_urls.py
This have some advantages that I like:
Models are in one place;
There is a possibility to run two separates nodes - based on needs.
Your development settings should be able to run dev server as a whole. Combing the settings from front and rest.
There is a clear code separation - and we know what is what in above structure.
If you have any more question - please ask.
Also I am curious what the others have to say - and how they handle issues pointed by me :)
Happy coding!

Extendable reusable app

I have the need for a reusable and extendable app for django, but am unsure on how to design it.
The reusable app is a double entry accounting system. The app has a few models, most importantly an Account and a Transaction model. Transactions depend (indirectly) on Account. Implementing this part by itself is not a problem and I have a good sense of how the system would work if it were on its own.
Problems arise when I try to implement this as a reusable app. I have two main issues that needs to be solved. Firstly, I would like there to be a separation between each app that uses the accounting app, i.e. app A should not be able to access accounting data created by app B and vice versa. Secondly, the apps using the account app usually needs to associate an account to some other entity, e.g. a client, guest, contractor etc. In order to be able to find accounts belonging to a each entity.
The more I think about it the more I am leaning towards just defining an interface (Mixins?) and use duck typing to have the accounting app contain common functionality (mostly reports) and let each app define the Account and Transaction models it needs. I get great separation, but some lack of reusability which I can live with. It would be neat to have a central accounting app that does the two things above, but it feels impossible to get both the extensibility and reuseability at the same time.
Any suggestions would be greatly appreciated.

Django - dividing functionality into apps

I'm working on a subset of my projects functionality, and I'm trying to focus on breaking my project into focused apps (as opposed to one monolithic app that does it all). After some googling, I want to keep each app tight and focused. However, I'm not exactly sure of the best way to divide up my code.
The overall functionality has three basic components:
Employees and their associated information.
Certificates/employee training and certificate information. Basically different types of training employees can receive and associated information.
Employee certifications (this links certificates to employees).
I have three main models: Employee, Certificate and Certification (which shares a relationship with both Employees and Certificates).
I could throw all three into a single app, as all three objectives are somewhat related, or, I could divide up the work. In the latter, two of the three are easy: employees and certificates can both exist without the other and have their own app, but certificates I'm not so sure about.
I could:
Bundle certifications in the employee or certificate app
Give certifications their own app
What say you? Does this scenario warrant more than one app? And if so, how should the three functionality requirements be divided up to keep each one tight and focused?
I would keep them all in a single app. It's too simple of an app (personally) for me to break it up. I would take advantage of django.contrib.auth.models.Users and build off of that in a structure which looks like this.
To take advantage of the users structure you need to extend the User model. Stackoverflow answers here and official documentation here.
HTH
I would advice to keep them in a single app : so all your models go into a single models.py,
and rather have multiple views.py (say for every functional unit).
This way, you can manage your models easily and also hit the right views file as required.
Keeping in multiple apps in this case would be an overkill, as there is no clear demarcation between the functionalities.