"polls.apps.PollsConfig" and "polls" in `INSTALLED APPS' - django

To tell Django which apps are installed, the official documentation introduces
The advantage 'polls.apps.PollsConfig' over 'polls'
setting.py
INSTALLED_APPS = [
#my APPs
"polls.apps.PollsConfig",
]
This explicitly refer to the installed app in app.py
from django.apps import AppConfig
class LearningLogsConfig(AppConfig):
name = 'learning_logs'
However, in some books, it tell it in a shortcut
setting.py
INSTALLED_APPS = [
#my APPs
"polls",
]
How Django access 'polls' in this situation?

Django can use either option. The version with the AppConfig lets you point Django specifically to an application configuration class which lets you specify some additional config for the app.
If you just want the app as-is, refer to it by its name alone. Use the AppConfig variant only when you are supplying an AppConfig class to configure something about the application.

In the manage.py location Django will check with the string you have given in installed apps list.
Each string should be a dotted Python path to:
an application configuration class (preferred), or
a package containing an application.

Related

Django / app import problem from submodule

I'm writing my own Django app, and trying to import submodule from my core library like that:
INSTALLED_APPS = [
'django.contrib.admin',
...
'core.login',
]
And interpreter gives me:
django.core.exceptions.ImproperlyConfigured:
Cannot import 'login'.
Check that 'core.login.apps.CustomloginConfig.name' is correct.
So login.apps looks like that
from django.apps import AppConfig
class CustomloginConfig(AppConfig):
name = 'login'
Are there any rules how I can edit this files to start Django properly?
apps.py file needs to be as so
from django.apps import AppConfig
class CustomloginConfig(AppConfig):
name = 'core.login'
This is where you tell django that I have registered this app 'core.login' and where to find it.
If login folder is in a core folder, then the above should work.
I think theres a lot of django apps out there that have organized things this way.
One being Kiwi but Im sure theres many others.

Impossible to use django-allauth when there is already an `account` app?

My Django application already has an app called account. Does it mean that it is ABSOLUTELY impossible to use django all-auth because of the name conflict? Due to the existing data, the app account cannot be renamed.
settings.py:
INSTALLED_APPS = [
...
'account',
...
# For allauth:
'django.contrib.sites',
'allauth',
'allauth.account', # Name conflict
...
If so, is there a good alternative?
2-14
Per solarissmoke's suggestion. Where should I put the new app and what is it name?
Is it something like this (Of course, it is wrong)?
my_project/account/apps.py:
import allauth.account
from django.apps import AppConfig
class AccountConfig(AppConfig):
name = 'account'
class AllAuthAccountConfig(allauth.account):
name = 'allauth.account'
label = 'allauth_account' # Change this
verbose_name = 'aullauth_account'
This is a known problem with django-allauth.
You can work around it by changing your own app to use a different app label. In your app's AppConfig:
class AccountConfig(AppConfig):
name = 'my_project.apps.account'
label = 'my_project_account' # Change this
verbose_name = 'account'
And refer to this app config in your INSTALLED_APPS, e.g.,
INSTALLED_APPS = [
...
'account.apps.AccountConfig',
...
'allauth',
'allauth.account',
...
Which should now work because the app labels are unique. Note that the only issue with this is that database tables names for your account app will have to change so as not to conflict with the allauth app - this will require some data migrations (if on an established project) or creation of fresh migrations (if on a project where you can afford to clobber the database).
You can also do this with the allauth.account app if that's easier - just create a new app config anywhere in your project, e.g.,
my_project/allauth_apps/apps.py (make sure to also create __init__.py in this new directory):
class AllAuthAccountConfig(allauth.account):
name = 'allauth.account'
label = 'allauth_account' # Change this
verbose_name = 'aullauth_account'
And then in your INSTALLED_APPS replace account with my_project.allauth_apps.apps.AllAuthAccountConfig. As above, this changes the database table names.
you need to fork the git on your own and change the label
fork the source code from https://github.com/pennersr/django-allauth/
add unique label such as allauthaccount to app in django-allauth/allauth/account/apps.py on your own forked git
commit
add following line to your requirements.txt -e git+https://github.com/andylee0213/django-allauth#egg=django_allauth
do "pip install -r requirements.txt and pip freeze > requirements.txt" and check github link is still in requirements.txt
but my suggestion is, instead of not receiving updates and going through all this pain, just use other auth libraries. There are many other libraries that does not depend on all auth. check
https://medium.com/codex/django-allauth-vs-dj-rest-auth-vs-python-social-auth-vs-drf-social-oauth2-ef7d50f92d16

How is Django apps.py supposed to be used?

I'm using django 1.10.5
It seems that the apps.py file in app1 is not imported unless I explicitely set default_app_config = 'app1.apps.App1Config' in __init__ for that module.
Yet, in the docs I'm reading "New applications should avoid default_app_config. Instead they should require the dotted path to the appropriate AppConfig subclass to be configured explicitly in INSTALLED_APPS."
I'm reading that as including the module in INSTALLED_APPS like
INSTALLED_APPS = (
'...',
'app1',
)
And I do have that.
Maybe I'm confused by the language "dotted path to the appropriate AppConfig subclass" and maybe there's more to it than listing the main module?
My specific use is that I want to import handlers.py so it will be included in the application because it has some signal receivers that need to be listening.
To do that, I followed the advice in the docs which says "In practice, signal handlers are usually defined in a signals submodule of the application they relate to. Signal receivers are connected in the ready() method of your application configuration class. If you’re using the receiver() decorator, simply import the signals submodule inside ready()."
# apps.py
from django.apps import AppConfig
class App1Config(AppConfig):
name = 'app1'
def ready(self):
import app1.handlers
# handlers.py
from django.dispatch import receiver
from django.db.models.signals import post_save
from app1.models import App1
#receiver(post_save, sender=App1)
def say_you_did_something(sender, instance, **kwargs):
print("Action has been taken.")
But that does absolutely nothing...
Until I also add
# __init__.py
default_app_config = 'individual.apps.IndividualConfig'
Which is supposed to be avoided except for < 1.7?
So to restate the question in practical terms, what is the recommended way to make the project aware of the handlers.py file?
You've misunderstood the instruction. As it says, you need to include the dotted path to the AppConfig class itself in INSTALLED_APPS, not the app.
INSTALLED_APPS = (
'...',
'app1.apps.App1Config',
)
Replace
INSTALLED_APPS = (
'...',
'app1,
)
with
INSTALLED_APPS = (
'...',
'app1.apps.App1Config',
)
No need to add default_app_config in init.py
In the django 3.0 application documentation it is mentioned how to include dotted path.
Below is the excerpt from django application documentation https://docs.djangoproject.com/en/3.0/ref/applications/#django.apps.AppConfig.ready :
For application authors¶
If you’re creating a pluggable app called “Rock ’n’ roll”, here’s how you would provide a proper name for the admin:
# rock_n_roll/apps.py
from django.apps import AppConfig
class RockNRollConfig(AppConfig):
name = 'rock_n_roll'
verbose_name = "Rock ’n’ roll"
You can make your application load this AppConfig subclass by default as follows:
# rock_n_roll/__init__.py
default_app_config = 'rock_n_roll.apps.RockNRollConfig'
That will cause RockNRollConfig to be used when INSTALLED_APPS contains 'rock_n_roll'. This allows you to make use of AppConfig features without requiring your users to update their INSTALLED_APPS setting. Besides this use case, it’s best to avoid using default_app_config and instead specify the app config class in INSTALLED_APPS as described next.
Of course, you can also tell your users to put 'rock_n_roll.apps.RockNRollConfig' in their INSTALLED_APPS setting. You can even provide several different AppConfig subclasses with different behaviors and allow your users to choose one via their INSTALLED_APPS setting.

Dotted name in AppConfig

With django 1.7 they added support for configuration classes instead of the magic string from previous versions.
My project has several applications into a folder named apps which is added to the PYTHON_PATH.
After adding a simple AppConfig derived class I'm running into many import errors and I want to rule out silly mistakes.
Suppose this structure:
project_root/
my_project/
apps/
my_app/
another_app/
Would it be correct to have this config?:
# my_app/apps.py
class MyAppConfig(AppConfig):
name = 'apps.my_app'
# my_app/__init__.py
default_app_config='apps.my_app.apps.MyAppConfig'
# settings.py
INSTALLED_APPS = (
...
'apps.myapp.apps.MyAppConfig'
...
)
Curently the project fails when trying to import models (or tasks or any other module) issuing:
from apps.my_app.tasks import AwesomeTask
ImportError: no module named my_app.tasks
I solved a similar issue by renaming the apps folder. It was somehow conflicting with Django internals system.
I hope this helps someone.

Should I remove 'django.contrib.comments' from my installed apps when I modify it by subclassing?

I'm customizing django comments.
According to the docs you'll need to add your customized app to INSTALLED_APPS in settings.py, and set COMMENTS_APP to your app name.
INSTALLED_APPS = [
...
'my_comment_app',
...
]
COMMENTS_APP = 'my_comment_app'
Should I also remove 'django.contrib.comments' from INSTALLED_APPS?
If you are only extending contrib.comments not replacing it, you shouldn't remove it from installed apps since, for example, most of the templatetags you need are in that application.
In order for Django to find the templates, templatetags and so on app must be in the installed apps.