"Project" vs "App"

183 views
Skip to first unread message

guettli

unread,
Nov 19, 2015, 4:54:40 AM11/19/15
to Django developers (Contributions to Django itself)
I created a ticket to find a better definition of "Project" vs "App"

https://code.djangoproject.com/ticket/25748

I am happy since Tim Graham accepted it.

Here are the current docs: https://docs.djangoproject.com/en/1.8/ref/applications/#projects-and-applications

Here is my view of Project" vs "App". It would be nice to find a consensus and update the docs.

Project
======
A project is a container for apps.
It contains only settings, no database models.
Since it contains no database models it does not contain database schema migrations.
It can contain migrations which fill a database with project specific data.
It is common that there is only one production installation of one project.
It is common to have several stages (dev, test, prod) for one project.
A project might contain a sitecustomize.py

App
===
An app can have models, views and code.
It should be re-usable.
An app can depend on other apps.
It must not depend on a project.
An app can contain a settings.py for testing, but it contains no settings on its own.
It should have instructions which settings are needed to get the app running in a project.
A app must not contain a sitecustomize.py.

Collin Anderson

unread,
Nov 19, 2015, 9:12:16 AM11/19/15
to django-d...@googlegroups.com
What's a sitecustomize.py? :)
I think apps _can_/_may_ be reusable. I have plenty of non-reusable apps. Why should they be reusable?
I think apps _should_ not depend on a project.


--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-develop...@googlegroups.com.
To post to this group, send email to django-d...@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/1a7e8d69-1970-4b07-b820-90c4d652486b%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

guettli

unread,
Nov 20, 2015, 6:14:49 AM11/20/15
to Django developers (Contributions to Django itself)


Am Donnerstag, 19. November 2015 15:12:16 UTC+1 schrieb Collin Anderson:
What's a sitecustomize.py? :)


This module is automatically imported during initialization if the interpreter.

We use it to:

 - sort sys.path.
 - monkey patching. During the Update from Django 1.6 to 1.7 we added an empty django.setup() to make code work on 1.6 and 1.7

See https://docs.python.org/2/library/site.html



 
I think apps _can_/_may_ be reusable. I have plenty of non-reusable apps. Why should they be reusable?

Yes, you are right. In my context we focus on re-usablity. We create software which gets used by
several customers (each running in their intranet). If you have only one plattform, then the
"should" is too strong.
 
I think apps _should_ not depend on a project.


If an app depends on the project there is a circular dependency. This should be avoided.
See https://en.wikipedia.org/wiki/Circular_dependency

That's why I vote for "An app must not depend on a project".

Thank you Collin for your feedback. I still hope some other people join this thread.

Regards,
  Thomas

 

Remco Gerlich

unread,
Nov 20, 2015, 8:18:51 AM11/20/15
to django-d...@googlegroups.com
So it seems a sitecustomize.py is something internal to your company, and you are proposing to document this for Django in general. So that shouldn't be in there, right?

Also, although circular dependencies are probably a sign of a less than perfect design, reality isn't perfect and they sometimes happen. Django allows them just fine, so its docs should not say that some kinds of dependencies are not allowed. They are.

Also, projects can be apps themselves. You can have your project's package in INSTALLED_APPS, and I believe that that is in fact a pretty common pattern. In particular, in the situation that you describe where you test an app using its own settings.py, you are using the app as a project and an app at the same time.

Also apps *may* be re-usable, and if they are then it is nice if they have instructions for settings somewhere, but I don't see that as part of an explanation of what an app is.

The current docs ( https://docs.djangoproject.com/en/dev/ref/applications/ ) say "A project is defined primarily by a settings module." and "The term application describes a Python package that provides some set of features. Applications may be reused in various projects."

And I feel that getting more specific than that means that you probably forget uses case that people use in production.

To me, apps are equivalent to modules. There are many reasons to divide code into modules (your original module becomes too large, you want to reuse parts of your code, you want to make dependencies explicit, etc). For instance, you may want to split your models module, or your urls module, or your views module. It usually makes sense to divide them together, because they are often coupled. So that becomes an app.

Greetings,
Remco Gerlich


--

Asif Saifuddin

unread,
Nov 20, 2015, 10:18:10 PM11/20/15
to Django developers (Contributions to Django itself)
Without the part of sitecustomize agree with the other parts.

+ there should be distinction between projects app and install apps


Reagards

Aymeric Augustin

unread,
Nov 21, 2015, 2:36:21 AM11/21/15
to django-d...@googlegroups.com
Hello Thomas,

Thanks for bringing this up. There’s definitely some room for improving the documentation — I know because I wrote it.

In terms of organization, I’d rather discuss how each topic (settings, models, etc.) relates to projects and apps than talk first about projects, then about apps. Otherwise there’s some repetition between the two sections and it’s harder to compare.

Your proposal touches many topics and was a good base for brainstorming. My thoughts below.


Project
======

A project is a container for apps.
=> Yes.

It contains only settings, no database models.
=> It’s also considered a good practice to put templates and static files at the project level (rather than spread across apps, even though Django supports it for pluggable applications. I would focus on saying that “models can only live within applications”. It’s part of the design of the ORM.

Since it contains no database models it does not contain database schema migrations.
It can contain migrations which fill a database with project specific data.
=> You’re going to confuse people to no end if you evoke MIGRATION_MODULES, a highly advanced and tricky concept, in an introductory document. I wouldn’t discuss migrations at all here. Stick with models.

=> You could say something about fixtures, which can live either at the project or app level. However the argument for putting them at project level is as strong as for templates and static files. I’m not sure you could say something sufficiently clear to enlighten readers.

It is common that there is only one production installation of one project.
=> You could also say that a project often corresponds to a website.

It is common to have several stages (dev, test, prod) for one project.
=> I usually say “environment”, not “stage”.

A project might contain a sitecustomize.py
=> There’s a consensus for saying that this is an uncommon technique in the Django world, albeit a legitimate one. Better not mention it in an introduction.


App
===
An app can have models, views and code.
=> And plenty of other things :-) migrations, translations, URLs, templates, template tags, static files, etc.

It should be re-usable.
=> I’d rather say “As much as possible, it should encapsulate an aspect of a project. Some apps are reusable, which means they can be shared between various projects. Reusable apps, sometimes called pluggable apps, are the most common way to distribute Django-related libraries."

An app can depend on other apps.
It must not depend on a project.
=> Technically, almost every app depends on a project in the sense that they require proper configuration of the project. This needs careful wording to avoid confusion.

An app can contain a settings.py for testing, but it contains no settings on its own.
=> This is correct but I’m not sure it’ll be useful to people who have barely heard about reusable apps or unit testing, let alone how both interact with Django’s requirement to have a global settings module. They are the people an introduction to project vs. app targets. I would skip this topic.

It should have instructions which settings are needed to get the app running in a project.
=> Yes. This goes with the discussion of how projects depend on apps.

A app must not contain a sitecustomize.py.
=> As above.


This is not as easy to explain as it might seem for someone familiar with the concept…

I hope this helps putting together a patch! I’m happy to review or further discuss a proposal.

Best regards,

-- 
Aymeric.



Tai Lee

unread,
Nov 22, 2015, 12:42:46 AM11/22/15
to Django developers (Contributions to Django itself)
I'm not sure about saying that a project is a "container for apps", and that a project contains "only" settings and "no database models".

At a basic level, a "project" can be just a settings module, but it may include other things.

Apps that are sub-packages within a project are generally not pluggable or re-usable in other projects. Pluggable apps that are developed along side a project can and should ideally be in their own repo, but definitely should have their own top level namespace.

A project should only "contain" apps that are tightly coupled to the project and/or each other. In this case the use of apps is more to to make navigating a large code base easier, than to facilitate re-use and the creation of pluggable apps.

A "project" can also be an "app" and define database models. You just add your "project" to `INSTALLED_APPS`.

I often find it convenient for the "project" to also be the main "app". It seems redundant to have two packages, one for the "project" and one for the "app" when they would both logically derive their name from the site.

To avoid a top level namespace conflict, I have often seen generic top level package name like `project` or `djangosite`, which make it difficult to then install one site's code as a dependency for another site. Or we end up needlessly repeating the name and having the app as a sub-package (e.g. `foo.foo`).

The best options if they are to remain separate seems to be to have a generic sub-package for the project (e.g. `foo.project`) or app (e.g. `foo.base` or `foo.core` or `foo.main`), which allows `foo` to be more easily used as a dependency in another project.

The former seems a little counter intuitive, as one might assume that a project is a container for apps (though it is not always and doesn't have to be).

The latter is problematic because "base", "core" and "main" are not very good app names. In that case, you'd likely want to set the app label for your models and the verbose name for your app config to "foo" anyway, so you might as well just make `foo` your app as well as being your project.

The things most likely to be confusing when treating a project as an app are:

1) The project's root URLconf and the app's URLconf.

An app's URLconf doesn't normally include URLconfs from other apps, but a project's root URLconf does. This confusion could largely be eliminated by changing the name of the default root URLconf in the startproject template and in the docs to `root_urls.py`.

This makes it clear what's what, and would allow the app URLs to be used more easily in other projects.

2) Project `TEMPLATE_DIRS` vs the `templates` directory in an app.

Although to be fair, I've seen many developers struggle just as much (if not more) with where to save and where to find templates when the project and main app are completely separate. It can take a while for newcomers to understand the difference, and then they often remain unsure of where they should save a new template and where they should look to find a template they need to edit.

I think this problem would be reduced by having the project also be the main app, and for its `templates` directory to be `TEMPLATE_DIRS[0]`. Ancillary apps would still have their own `templates` directories, but for the most part people would only need to look in one place to edit a template for the project, and they would be less likely to save a new template in the wrong place.

When used as a dependency in another project, all the templates would be available (not only app templates), but they would no longer be in `TEMPLATES[0]` so the other project could easily override anything. With separate projects and apps, the other project might not have access to all the templates, unless they explicitly add the first project to `TEMPLATE_DIRS`.

Cheers.
Tai.
Reply all
Reply to author
Forward
0 new messages