Why do we need apps?

So am I right to assume that when you placed a model in an app, the models stays there forever (even if it no longer makes sense), unless you’re willing to do manual database work which doesn’t make any sense (that is why we use Django in the first place)? A problem like that would never happen with using a single app per project (you can shuffle models between modules at any point in development).

How is this a great development practice? This approach requires to spec out the project in perfect detail upfront to model the apps and models, in other words a waterfall approach (or live with the fact that your code structure doesn’t make sense as your codebase grows). The Django website says that the framework “encourages rapid development”, but encouraging the use of apps basically prevents to use agile practices effectively.

2 Likes

I think you’re overstating the case a little for how hard it is to move models around :slight_smile: It’s totally possible to develop iteratively while splitting your code into multiple apps! It’s not particularly pleasant but you can do it using just the migrations framework. I think it would be great if Django was better at handling this (but I’m not volunteering to do the work so I accept the compromise). I’ve done this kind of surgery on a work project a few times and it’s not been a big obstacle.

Sure, nothing will save you from bad process. But having your models divided up into different apps can avoid unnecessary process when different people are working on different bits of code.

Could you please tell me more about the process of moving a model from one app to another (considering this model has foreign keys with models from other apps)? I assume that this is why Django docs recommends to start a project with a custom user model since it’s a nightmare to migrate the model later

Could you please tell me more about the process of moving a model from one app to another (considering this model has foreign keys with models from other apps)?

Can’t you just set db_table to keep the old table name ? Of course you will need to change the app name in your foreignkey definitions but then I think it should work.

Exactly what I did in this situation, plus for deployment I had to delete some lines from django_migrations and fake apply them. Not really sure of the top of my head, but let us know if you would like more detailed a tutorial.

It’s more complicated than that.

Literally the first line in the answer to the question “how to move a model between two apps” is “*don’t do it!!*”.

1 Like

I don’t see how the other way presented in the stackoverflow answer invalidates my suggestion, but anyway the answer proposes pretty much a custom migration in addition to code changes which seems like a routine operation to me. But like someone in the ticket said IIRC: perhaps Django could provide a specific operation for this kind of migration to make it easier.

Also don’t miss that part:

Would you like to suggest ways Django could make it easier ? Perhaps not removing apps, I recon we’re probably many to love the app system, not only to ensure code isolation but also to ease reuse.

I’m not suggesting to remove apps. I’m suggesting to use single app per project.

The only real feature of using multiple apps per project approach is that you can have two models with the same name within a project (by defining them under separate apps).

Another potential feature is that multiple app reduce migration conflicts. I don’t fully agree with this one since apps don’t solve this issue per se, development process does. Unless you define the development process as “each team member should only work on a single app at a time”, nothing stops a developer to work on the same app as their coworker. So if we’re defining the development process we might as well specify how the migrations should be done when doing the work on parallel branches. Here’s a thread about this topic. Finally, if a team experiences migration conflicts and decides to solve it by assigning a team member per app, that means that the app structure is now driven by a team-app assignment (new apps might be created so that devs could work without conflicts) rather than organically (moving code to a separate app so that the code structure makes more sense). What I’m trying to say is that apps are not a solution to the migration conflicts problem.

Now when it comes to disadvantages we have the problem of moving models between apps. Saying that it is trivially fixable by writing migration files manually is like saying: “if you have a migration conflict, you could just solve it by manually modifying the migration files”. The point of a high level framework is to speed up the development process as much as possible. Another problem is that developers are confused about the difference between apps and projects. It is also not clear how to structure your code when you start a project: Django forces you to come up with a name for the project and a name for the first app. This assumes that we know the total number of apps (and the models) we’re going to have upfront – this is not agile.

Sure, but some things are more common than others: especially in smaller teams, it’s common that people work on the different bits of the code - and if you’re using multiple apps, this avoids migration conflicts. I have a team of 3 and conflicts have happened a couple of times in the last year with multiple (~11) apps. If we had one app it would be something we’d need to deal with every week. Moving models around, though, happens fairly rarely. I think I’ve moved around 3 or 4 models over the last year. Something doesn’t have to be perfect for it to be good or useful :slight_smile:

1 Like

Apps are one of the best things in Django. And I miss them so much when I have to work with other frameworks!

Apps let you split your code, keep it more organized, allow multiple teams to work on different parts of the project.

I see apps as Python modules on steroids; the only thing that differs an “app” from a package is the presence of apps.py file with a config class in it. That’s all; if you don’t use models or templates, you don’t have to follow conventions. Views can be put into controllers.py if you want to, there aren’t many limitations.

But to keep your code more organized, it’s an excellent habit to follow well-established conventions. Trust me. You’re not a single person who’ll be working on the project, think about yourself coming back to the codebase in a year, that will be another guy, not you, help him today!

And regarding early buy-in, this is total BS; you can refactor your code anytime. Split it into even more apps or merge several apps. The only thing that could get in a way is the table name of the model. By default, its name constructed from the app name and model name, but if you manually set table names in a model’s options, the issue will be gone, just get used to it, do something like:

class Page(models.Model):
	class Meta:
		db_table = 'page'

I hope it helps.

2 Likes

TBH, you get a sense of what app you need to make to host what model and in which directions you want your apps to be coupled after using Django for a while.

I think the easy way would be, before adding a model: ask yourself why it shouldn’t be in its own app, this should save you some model moving in the future.

However, I do like the idea of grouping a model with its features such as views, urls etc … wait, that’s exactly what apps allow you to do.

Maybe check how django-autocomplete-light is structured: it’s a python package which is composed of several python modules, that’s also something setuptools allows you to do.

Just as an anecdotal data point: I don’t work in large teams/multi-team projects, I usually work on my own or with up to two or three others. I still enjoy apps a lot, even if I may not always use them as intended. When my projects have strongly separated frontend parts (like an administrative one, one for the API, and one for customers/users), I like to separate them into different apps for URL and template namespacing. This breaks up huge template/view modules into smaller ones, which helps me reason about the structure of my application.

(I have less use cases for splitting models over apps – I usually start out doing it, and then later it turns out that my models are more tightly coupled than I thought in the beginning, and that shoving them in a core or default app would’ve been better, or at least no worse.)

This is indeed “use not as intended” – your apps are not defined by the functionality they provide, but rather by the way the functionality is exposed. It could be said that where the recommended division (and the one most fitting reusable apps) is “vertical”, yours is “horizontal”.

That is interesting.

And regarding early buy-in, this is total BS; you can refactor your code anytime. Split it into even more apps or merge several apps. The only thing that could get in a way is the table name of the model.

Table name is not the only problem, from the top of my mind I can say that content type framework may cause problems during model movement.

I have a team of 3 and conflicts have happened a couple of times in the last year with multiple (~11) apps. If we had one app it would be something we’d need to deal with every week.

That’s true but it doesn’t feel like a big problem, 99% of such conflicts can be easily fixed with rm migration && makemigrations or just makemigrations --merge, on your CI you can have makemigrations --check step that will fail if pr has migration conflict.

Hi. I am fairly new to Django, although not completely alien to web development (Rails, Phoenix,…).

My understanding of “apps” so far is it’s just a way of grouping related functionality. Sort of like putting stuff naturally to folders. So you’d have everything related to users in one “app” (folder), and everything related to products in another “app” (folder). Each of these apps could be a few models, but it shouldn’t be a single model file with 20 models - that’s probably a good sign stuff should be split.

Also another guiding principle I’m thinking of is that app is typically something that lives under its own URL endpoint. So for example /users (and all related stuff) and /products (and all related stuff). Although I understand this is very rough estimation, it’s never really simple as that.

Rails has fairly different way of organising stuff, but Phoenix does have something called Contexts, which seems fairly similar to Django apps. See Contexts — Phoenix v1.5.7

Would you say my understanding is ok-ish, or am I completely wrong and misguided somewhere, please?

Thank you!

1 Like

Yes, I think your understanding of apps in Django is correct based on how you described them.

1 Like

This is an interesting discussion – i found it after googling ‘why does django have apps’.

I hate all frameworks and am hoping to find the one i hate the least. i used django 10 or 15 years ago, and revisting for a bit now.

i was going thru the ‘build your first app tutorial’ and got confused when i realized the app, ‘polls’, was given a directory next to the ‘mysite’ directory, which is named so because the project i created to hold all the apps is called ‘mysite’.

https://docs.djangoproject.com/en/3.2/intro/tutorial01/

duplicate directory/subdirectory names is confusing to me.

having an ‘app’ next to a ‘project’ folder is confusing to me.

having ‘apps’ inside my app – my web app, my web application, the one i’m building – is confusing to me. i’m a bit of a psycho when it comes to the importance of naming, tho, so.

the idea that you would need multiple django apps out of the gate is confusing to me. for instance, let’s say the application i’m building has 10 ‘modules’ or ‘areas of functionality’, and each had 30 or 40 models, views, whatever – that’s totally fine – they can get their own directories. i don’t want a big crazy directory structure - i just want a general idea of where things are, and my IDE or command-completion will help me get to them. i think of the ginormous java-based frameworks from back in the day – disaster. the idea that you have to have this logical separation of pluggable apps seems like overkill to me – sort of like how we all used to talk about, “Well, we can’t use Oracle-specific SQL because, you know, we might want to migrate to SQL Server at some point.” Of course we never migrated to SQL Server or anything else. :smiley:

all that said, i’m currently hating Django less than all the other frameworks out there. :slight_smile:

Laravel is still in the running, tho their new version dialed-up the Java-oriented abstraction-for-abstraction-sake crazy to a new level.

and Rails is in the mix despite the distasteful stuff going on with its owners.

one case i could see for an ‘apps’-like structure is something like SaasPegasus – a saas boilerplate framework for django that i’m a fan of despite having never used it.

in this case, i could see wanting to be able to plot that in its own ‘app’ directory and have it be separately-upgradeable, bug-fixable, etc. – completely outside the scope of my own stuff. maybe that couldn’t happen without the ‘apps’ complexity that is currently built into django, but i doubt it.

i would also say, i appreciate the stability of django. so, if someone asked me, as benevolent dictator, would i scrap ‘apps’, i’d lean heavily towards ‘yep’. i’d listen to the args, etc., but i’d at least like to find a way to simplify things so that a starter project would not have a project and project subdirectory, and separate ‘apps’ directories and the need to wire up your app with the ‘core’ app/project – it would all just work out of the box.

that’s a funny part about Nuxt – the JS framework for the Vue framework (yes, framework for a framework) – they have super-advanced feature called ‘file system routing’ – you drop a page/vue component inside a certain directory, and voila – you can then put that path in your browser location bar and the page just shows up!

if Django were javascript-based, it’d already have 10 new and popular direct siblings/competitors, splintering everything.

i’m gonna study that Beith and other layouts just for kicks.

i wonder if you could accommodate the existing apps system, but create a new create ‘startapp’ switch called ‘–keepitsimple’ that effectively removed ‘apps’ from the framework.

1 Like

@knivets - I recently started working on a Django project for the first time, and you perfectly articulated the same thoughts I had.

PRs are always welcomed! At the end of the day if django doesn’t do something you’re free to fork it and make it work as you like. I quite like apps; they’re not perfect, but I acknowledge some of the historical and technical tradeoffs made.

That’s not how this works. I opened ticket for similar issues on the tracker, but they were flagged wontfix. I think the first step would be a willingness to change from the core team and acknowledging issues. Submitting a PR is not a big deal

One point to recognize is that the “multiple apps” structure is not mandatory. There is nothing that forces you to either implement multiple apps or have a project subdirectory at the same level as your app or even have a separate app directory from the project subdirectory.

So what you’re looking to “fix” isn’t something “wrong” with Django, but a set of conscious design decisions.

How you choose to organize your projects is really up to you.

Don’t need apps? Don’t use them.