How independent should Django apps be from one another? - django

I'm having trouble determining how I should split up the functions of my project into different apps.
Simple example: We have members, and members can have one more more services. Services can be upgraded, downgraded, other services added on, and can also be cancelled. (This is extremely simplfied, were it that simple in reality I'd use a pre-made solution)
My first thought was to make this into a 'member' application, and then a 'services' app that takes care of renewals, up/downgrades and cancellations.
I then thought I should probably make a renewal app, an up/downgrade app, and a cancellation app. But, these apps would all depend on the same table(s) in the DB (members and services). I thought applications were supposed to be independent from one another. Is it ok to make applications that are heavily dependent on other apps models?
Along the same lines, which application should I use to store the models to create the services table if so many apps use it?

I think you first thought was right: you don't get so many benefits of splitting everythin into multiple apps, and on the contrary it could become messy and hard to mantain.
The Django way of doing things depends a lot of the models. Each object is mapped to an entity on the data model. Your apps are mostly organised in relation to such data model. So, if you have an entity (service) that has different pieces, it is better to understand such pieces as parts of the same thing. The other entity (member) should be another one since it is a different thing.
There is no penalty of importing models from different apps. The most important thing is anyway building data model to be consistent.

The point of apps is to allow code which is intended to be reused as an addon by third parties. You probably won't want to split your projects up much, if at all into apps.

Related

Should I use an internal API in a django project to communicate between apps?

I'm building/managing a django project, with multiple apps inside of it. One stores survey data, and another stores classifiers, that are used to add features to the survey data. For example, Is this survey answer sad? 0/1. This feature will get stored along with the survey data.
We're trying to decide how and where in the app to actually perform this featurization, and I'm being recommended a number of approaches that don't make ANY sense to me, but I'm also not very familiar with django, or more-than-hobby-scale web development, so I wanted to get another opinion.
The data app obviously needs access to the classifiers app, to be able to run the classifiers on the data, and then reinsert the featurized data, but how to get access to the classifiers has become contentious. The obvious approach, to me, is to just import them directly, a la
# from inside the Survey App
from ClassifierModels import Classifier
cls = Classifier.where(name='Sad').first() # or whatever, I'm used to flask
data = Survey.where(question='How do you feel?').first()
labels = cls(data.responses)
# etc.
However, one of my engineers is saying that this is bad practice, because apps should not import one another's models. And that instead, these two should only communicate via internal APIs, i.e. posting all the data to
http://our_website.com/classifiers/sad
and getting it back that way.
So, what feels to me like the most pressing question: Why in god's name would anybody do it this way? It seems to me like strictly more code (building and handling requests), strictly less intuitive code, that's more to build, harder to work with, and bafflingly indirect, like mailing a letter to your own house rather than talking to the person who lives there, with you.
But perhaps in easier to answer chunks,
1) Is there REALLY anything the matter with the first, direct, import-other-apps-models approach? (The only answers I've found say 'No!,' but again, this is being pushed by my dev, who does have more industrial experience, so I want to be certain.)
2) What is the actual benefit of doing it via internal API's? (I've asked of course, but only get what feel like theoretical answers, that don't address the concrete concerns, of more and more complicated code for no obvious benefit.)
3) How much do the size of our app, and team, factor into which decision is best? We have about 1.75 developers, and only, even if we're VERY ambitious, FOUR users. (This app is being used internally, to support a consulting business.) So to me, any questions of Best Practices etc. have to factor in that we have tiny teams on both sides, and need something stable, functional, and lean, not something that handles big loads, or is externally secure, or fast, or easily worked on by big teams, etc.
4) What IS the best approach, if NEITHER of these is right?
It's simply not true that apps should not import other apps' models. For a trivial refutation, think about the apps in django.contrib which contain models such as User and ContentType, which are meant to be imported and used by other apps.
That's not to say there aren't good use cases for an internal API. I'm in the planning process of building one myself. But they're really only appropriate if you intend to split the apps up some day into separate services. An internal API on its own doesn't make much sense if you're not in a service-based architecture.
I cant see any reason why you should not import an app model from another one. Django itself uses several applications and theirs models internally (like auth and admin). Reading the applications section of documentation we can see that the framework has all the tools to manage multiple applications and their models inside a project.
However it seems quite obvious to me that it would make your code really messy and low-performance to send requests to your applications API.
Without context it's hard to understand why your engineer considers this a bad practice. He was maybe referring to database isolation (thus, see "Working multiple databases" in documentation) or proper code isolation for testing.
It is right to think about decoupling your apps. But I do not think that internal REST API is a good way.
Neither direct import of models, calling queries and updates in another app is a good approach. Every time you use model from another app, you should be careful. I suggest you to try to separate communication between apps to the simple service layer. Than you Survey app do not have to know models structure of Classifier app::
# from inside the Survey App
from ClassifierModels.services import get_classifier_cls
cls = get_classifier_cls('Sad')
data = Survey.where(question='How do you feel?').first()
labels = cls(data.responses)
# etc.
For more information, you should read this thread Separation of business logic and data access in django
In more general, you should create smaller testable components. Nowadays I am interested in "functional core and imperative shell" paradigm. Try Gary Bernhardt lectures https://gist.github.com/kbilsted/abdc017858cad68c3e7926b03646554e

Create a separate app for my REST API or place it inside my working app?

I'm building simple gis system on geodjango.
The app displays a set of maps and I'm also attempting to provide a RESTFUL API for these maps.
I'm facing a decision whether to create a separate app for the API or to work inside my existing app.
The two apps are logically separate but they share the same models.
So what is considered better?
Although a case can be made for either of the approaches, I think keeping the APIs inside their associated apps would be a better one. Since the code in APIs is going to depend on the models, or other utility methods anyway, keeping APIs in the same app would lead to more cohesive code. Besides the very ideology behind Django apps is that they can be isolated and reused.
There used to be a similar case with storing the templates. In the initial days of Django, people used to prefer to store all the templates altogether in the same global folder (with subdirectories by the names of the app), however, in recent times even Django has started discouraging the said approach in the favour of storing templates in the respective app itself.
#hspandher's answer is very solid and will allow for most of your needs to be implemented.
There is though another approach which may be a bit more complicated to achieve but gives you all the space you may need for experimentation and reusability potential:
Separate everything:
Backend:
Isolate your API from its visualization (see frontend below) and make it completely autonomous and self-contained.
That can be achieved by separating your apps inside your Django project and expose the corresponding APIs which must be the only way for an external factor (ex. client, another app etc.) to "talk" with any one of your apps.
Frontend:
Assuming that you have your APIs exposed, you effectively separated the visualization from the logic and therefore you have many options on how to visualize your maps.
For example, you can now build a React app which can make requests to your API and visualize the responses by using any of those tools: leaflet.js, D3.js, or anything that you like really.
Summary:
The benefits of this separation are:
Separation of logic and implementation.
Better maintainability.
Many tool and technology options to use.
Reusability.
As a side note, you can read about 12 factor method and think about using it in your implementation.

Django - How to Modularize a large web Application?

I'm trying to figure out the best way to build a large web application, but keeping the various logical sections modularized. For example, there will be a number of different logical sections:
Estimates
Work Orders
Accounting
Contacts
etc...
As much as possible, I want to have the code for each of these modules disconnected from all the other modules. If code from one section starts to throw errors or cause incorrect data, I don't want that to affect other modules.
My first thought is just to separate by using Django 'apps'. Each module is its own app. Then, if I build each app to be "pluggable", then the code is self sufficient. However, the problem with this approach is that the modules will likely need to access the models of other modules. For example, the 'Accounting' module will need access to the 'Contacts' model, since we want to send invoices to people in our contacts list.
I looked into having a completely separate Django project for each module, but that poses problems (I think) for user authentication. Plus, to my knowledge, multiple Django projects can't (easily) share one database.
Just wondering if there are any good ways or best practices to make logically separate 'modules' while, as much as possible, keeping the code from one module completely isolated from the rest, but still having a cohesive web application.

better architecture in django is different apps. or single App for different components?

I have intended to have an app. where I want to have different things having relations with each other and want to know that whether I should have them as just different models or as differnt apps. Obviously if this is student, teacher in LMS then they are necessary component of LMS while if this is Job, Professional and Company then there can be different things associated with a job , a professional can have his full profile with different features, company can have different directory listing e.t.c. like features.
So Company and professionals who are users also should be as diff. apps. and job as different app.? Will this way be fine? as Jobs app. don't always everywhere need to have professional data or employer all data other than just name. So it seems like it is more convenient to have them as diff. apps, so that it can be used somewhere else.So is that right way?
Or
As I also want this project to be flexible so will the above make it more complex? And should I just treat them as diff. models instead of diff. apps. as Company and Professional are users , for which django gives Profile features also. So is this right way?
Which way is better one?
thanks in advance.
There is no exact answer here, so it's my opinion.
It is always good to have several apps rather than one big app. Reasons:
apps becomes smaller and it's easier to maintain small pieces of code;
project structure becomes more clear, I just need to look at the file manager to see main parts of the project;
interaction between apps become explicit: easy to test and prevent unnecessary coupling.
Not every Django app should be pluggable. It's ok to have two apps that depend on each other (if you aren't going to distribute them seperately). It's like having two dependent functions: nothing is wrong with it.

Django best practice: number of model classes per file / directory structure

Another best-practice question to those with experience: How many models do you put in one file?
I've seen many examples that stuff all model classes into a single "models.py" file, which really feels wrong to me. In previous projects using other stacks I've gone with one file per model class. How is it done properly in Django for non-trivial applications with, say, 20 model classes? What would the directory structure look like?
Many people, especially those coming from the Rails world, get hung up on the term "application" and start throwing absolutely everything into a single app. In Django, an application is a single-use module that does one thing and does it well. Each application should be describable in one or two short sentences. A "project" is a collection of applications unified by a settings file. Even for something as complicated as an online store , something I'm discovering now, having more than four or five models in a single application is a warning sign: It was better that the store application (which has the shopping cart) be dependent upon upon the product application than have both in the same app. The same was true of invoices and payments, and so on.
Take a look at Django in the Real World, Jacob Kaplan-Moss's presentation about how to write Django applications.
A Django application is encapsulation: it describes one simple object (or collection of objects) and its API. Having 20 models sounds like you don't have a clean API, and therefore a clear concept, of what this app does.
The answer you want is "it depends on what your application does." To that end, what the Hell does an application with 20 models do, anyway? Grab your copy of Refactoring and have fun.