Say I have an app called polls.
What is the difference between including an app in INSTALLED_APPS like this 'polls.apps.PollsConfig' and just specifying the app's name ( 'polls')?
The official Django tutorial recommends the former.
The latter is the old way and it has got problems in some cases with the position in INSTALLED_APPS as the preferred way has been to put your apps the last, so all your dependencies are already available when your app is loaded.
The former is the new improved way when you load your app configuration instance first and so all the dependencies are aware of your app and also your app prior to loading has got all the dependencies available.
You should use AppConfig and put it at the top of the list, plain app positioned last is relict of the past.
Related
Problem description
I have django standalone app named django_codeserver. It can be loaded from my private package registry as a pip-package.
My app contains about twenty sub-apps for example django_codeserver.headers, django_codeserver.genders etc.
Current behaviour
To register all models in my project which uses django_codeserver, I have to register all the sub applications in the parent project INSTALLED_APPS such as:
INSTALLED_APPS = [
...
'django_codeserver.headers',
'django_codeserver.genders'
...
]
Preferred behaviour
I would want all the sub apps being registred in the parent project when I only:
Install the standalone django app as pip-package (pip install django-codeserver)
Register only the parent app in parent project installed apps:
INSTALLED_APPS = [
'django_codeserver
]
After researching this problem, I couldn't find the exact solution. However we can kind of deal with this problem as pointed out here.
So we are not able to automatically install sub apps, but instead we can reuse application with all sub apps included without directly write all apps in the parent project INSTALLED_APPS.
In that way reusable app installation documentation not changing after adding a new sub app. Also the maintenance of included sub apps is moved from reusable app consumer to its provider.
I'm new to Django and python in general and i'm trying to set up a RESTful api using Django and Django Rest Framework, so my problem is that i want to get rid of the default installed apps, something like this:
INSTALLED_APPS = [
#'django.contrib.admin',
#'django.contrib.auth',
#'django.contrib.contenttypes',
#'django.contrib.sessions',
#'django.contrib.messages',
#'django.contrib.staticfiles',
'rest_framework',
'myapp',
]
since i want a simple api (with no UI) that provides me with some data. But when i run python manage.py makemigrations i get the following error:
LookupError: No installed app with label 'admin'
does this mean these apps are essential?
Thanks in advance.
Keep in mind that Django Rest Framework inherit a lot from Django, and if you are using other packages they likely do the same too; you are free to remove some apps (e.g. django.contrib.sessions if you your are not going to use them) but it depends on what you are going to do in your project.
In particular the error you are referring to is caused by the removal of django.contrib.admin which provides the admin interface for your project, very useful in the development phase. You can read more about it here.
If you have created your app with the standard django-admin startproject and django-admin startapp by default you are importing the admin app form urls.py and admin.py files with this line of code:
from django.contrib import admin
Just get rid of it (and the consequent code in admin.py and urls.py which is referring to the admin app) and the error should go away.
Each application has its own purpose. You can learn more about that here:
django.contrib.admin: documentation;
django.contrib.auth: documentation;
django.contrib.contenttypes: documentation;
django.contrib.sessions: documentation;
django.contrib.messages: documentation;
django.contrib.staticfiles: documentation.
Once you understood the purpose of each app and having clear the features of your project and the packages you'll be using you can choose which applications are to be removed; although at least for the beginning, while you are learning, i personally suggest you to simply keep all of them just to be safe, considering that they are providing very basic functionalities.
After Django's 8 part tutorial there is an additional "Advanced Tutorial" which gives a quick-start like approach into python packaging. Namely, moving the Django tutorial app "polls" outside of a Django project and preparing it to be pushed to PyPi.
While this information is useful and covers a bit more ground that Python's own packaging tutorial (e.g. the MANIFEST file to include static / template resources). It doesn't quite explain how to make an app reusable in the sense of configurable options.
For example, if the app has a runtime dependency variable my_bool, how one would open up setting this option for their reusable app.
My first instinct was AppConfig. However, subclassing AppConfig for this purpose isn't explained in the documentation.
One could assume that all the options / settable variables come from the main settings.py file and set defaults if not there... but that also isn't explicitly stated or recommended in any of the Django docs that I have read thus far.
For a reusable application I am making, I would like the user to be able to augment the app with their own data files.
Thus they would need to supply these files in a directory somewhere (with a specified, designated structure) and then tell my app where they are e.g. MY_APP_DATA_DIR="os.path.join(BASE_DIR, <location>)".
Where would such variables go in a reusable Django app?
Would one use a dependency like python-decouple to grab these values?
Most documentation simply tells you to add the name of each of your apps to the INSTALLED_APPS array in your Django project's settings. What is the benefit/purpose of this? What different functionality will I get if I create 2 apps, but only include the name of one in my INSTALLED_APPS array?
Django uses INSTALLED_APPS as a list of all of the places to look for models, management commands, tests, and other utilities.
If you made two apps (say myapp and myuninstalledapp), but only one was listed in INSTALLED_APPS, you'd notice the following behavior:
The models contained in myuninstalledapp/models.py would never trigger migration changes (or generate initial migrations). You wouldn't be able to interact with them on the database level either because their tables will have never been created.
Static files listed within myapp/static/ would be discovered as part of collectstatic or the test server's staticfiles serving, but myuninstalledapp/static files wouldn't be.
Tests within myapp/tests.py would run but myuninstalledapp/tests.py wouldn't.
Management commands listed in myuninstalledapp/management/commands/ wouldn't be discovered.
So really, you're welcome to have folders within your Django project that aren't installed apps (you can even create them with python manage.py startapp) but just know that certain auto-discovery Django utilities won't work for that application.
I am working on an app, which requires another app to be installed. I can add it to my setup.py and it will install the other app too.
After installing my application, i need to add it to INSTALLED_APPS, but i need to add the external app too.
Is there a way to pass the other application implicitly?
What's the recommended way to handle that kind of dependency to avoid asking the users to add more than one app when it is required?
Without doing some strange hacking, there's no way to do this, nor should there be. The user should be aware of what they are adding to their project and what dependancies are required. Remember Django's design philosophy:
Explicit is better than implicit
Have a look at some of the following apps. They all require dependancies in the INSTALLED_APPS. They make it clear in the docs that the user has to add them to their project manually:
Django Zinnia
Django Admin2
Django Filer
Django Filebrowser
There is a library called django-autoconfig that lets you do this. You basically include an autoconfig.py in your app, and if your app is include in INSTALLED_APPS, it's autoconfig.py is loaded.
The file should look something like this:
SETTINGS = {
'INSTALLED_APPS': [
'external_app_1',
'external_app_2',
],
}
Read the docs for more information about ordering and more advanced stuff like that.