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.
Typically I'd set a value in settings.py and then use #override_settings in tests to override it.
Is there any similar mechanism that exists for overriding settings in apps.py when using
app_config?
For instance
# apps.py
class MyConfig(AppConfig):
SOME_VAR = "SOME_VAR"
# some .py file
from django.apps import apps
apps.get_app_config('some_app').SOME_VAR
# some test.py
# How to change the value that apps.get_app_config('some_app').SOME_VAR returns?
It's strange this isn't covered in the docs as it feels this would be a common use case or maybe I'm missing something?
Thanks,
I'm using Django 3.2. I've changed added this line to settings.py:
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
I then ran these commands:
$ python manage.py makemigrations
$ python manage.py migrate
The makemigrations command creates new migration files for my apps, not just the apps that I have created, but also in my dependencies. For example, I'm using django-allauth, and this file was created in my virtual environment (virtualenv):
.venv/lib/python3.8/site-packages/allauth/account/migrations/0003_auto_20210408_1526.py
This file is not shipped with django-allauth. When I deploy this application from git, this file is not included.
What should I do instead? How can I switch DEFAULT_AUTO_FIELD without the need to create new migration files for dependencies like django-allauth?
Ideally, your third party dependencies would include this line in the config found in apps.py:
from django.apps import AppConfig
class ExampleConfig(AppConfig):
default_auto_field = 'django.db.models.AutoField'
While waiting for upstream dependencies to update their apps.py or migration files, you can override the app config yourself. If it doesn't exist already, create an apps.py file in your main app directory (eg: project/apps.py), and override the config of a dependency. In this example, I'm overriding the config of django-allauth:
from allauth.account.apps import AccountConfig
from allauth.socialaccount.apps import SocialAccountConfig
class ModifiedAccountConfig(AccountConfig):
default_auto_field = 'django.db.models.AutoField'
class ModifiedSocialAccountConfig(SocialAccountConfig):
default_auto_field = 'django.db.models.AutoField'
Then modify INSTALLED_APPS in settings.py to look like this, replacing the old entries for django-allauth in this example:
INSTALLED_APPS = [
# ....
# replace: "allauth.account", with
"projectname.apps.ModifiedAccountConfig",
# replace: "allauth.socialaccount", with
"projectname.apps.ModifiedSocialAccountConfig",
]
If the dependency doesn't have an apps.py file to override, you can still create an AppConfig sub-class in project/apps.py like this:
from django.apps import AppConfig
class ModifiedExampleDependencyConfig(AppConfig):
name = 'exampledependency' # the python module
default_auto_field = 'django.db.models.AutoField'
Now when you run python manage.py makemigrations, no migration files should be created for the dependencies.
I work on a big project, we upgraded Django from 2.2. to 3.2 and then have got a need to create all new models with Big Integer (Int8) (PostgreSQL) field instead of default Integer (Int4).
When I defined it in settings.py:
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
I got the same problem, but with own apps - Django tried to make me to migrate 135 models I had, but I didn't want to do it. I only wanted to create new models with BigInt and manipuate olds manually.
I found the next solution. I changed the field to custom:
DEFAULT_AUTO_FIELD = 'project.db.models.CustomBigAutoField'
And then overrided its deconstruction:
from django.db import models
class CustomBigAutoField(models.BigAutoField):
"""Int8 field that is applied only for new models."""
def deconstruct(self):
name, path, args, kwargs = super().deconstruct()
if getattr(self, 'model', None):
path = 'django.db.models.AutoField'
return name, path, args, kwargs
As I discovered, fields of new models don't have a back reference to their models, so path wouldn't be overridden for them.
We override path because Django checks whether a model is changed by a key, that includes the path to this field. So we deceive Django and it thinks that existing model didn't changed.
I might not see the whole picture, but I tested it with different existing and new models and it worked for me. If someone tells me why this solution is bad, I'd be grateful.
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.
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.