Django Settings Apps Model - django

I want to know what is the meaning of "Config" in installed_apps in django like this
'polls.apps.pollsConfig'
Is it okay to put only the name of the apps example 'sample_apps'?

In the subfolder polls you have a file apps.py with a class named PollsConfig
polls/apps.py
from django.apps import AppConfig
class PollsConfig(AppConfig):
name = 'polls'
verbose_name = 'PollsApp'
This file is autogenerated by django when you create a new class but you can modify it to add some proprieties.

Related

virtualenv raises importerror because of changing app name in django

I've used [this link] to rename my django app. So I've edited some files and table's name and so on. But as it has been mentioned in that link, There is problem with virtualenv. So how can I fix it? I've change name "notes" to "blog".
The apps.py file:
from django.apps import AppConfig
class NotesConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'blog'
In the settings.py file:
INSTALLED_APPS = [
'blog.apps.BlogConfig',
// the rest installed apps
]
Lets say the name of this application is: blog and its following the normal folder structure django comes with.
so, the settings.py should be
INSTALLED_APPS = [
'blog',
]
and the apps.py should be
from django.apps import AppConfig
class BlogConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'blog'

Migrating models of dependencies when changing DEFAULT_AUTO_FIELD

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.

Django app_label is wrong on models

I have a Django DRF application. Here is my project structure.
myproject/
myproject/
apps/
myApp1/
__init__.py
apps.py
admin.py
models.py
urls.py
views.py
myApp2/
__init__.py
static/
manage.py
and myINSTALLED_APPS contains:
INSTALLED_APPS = [
'apps.myApp1.apps.AppOneConfig',
'apps.myApp2.apps.AppTwoConfig',
]
When I went to ./manage.py shell_plus and run:
SomeModel._meta.label
I see myApp1 or myApp2 instead of apps.myApp1 && apps.myApp2. And even in migrations Models are referred as myApp1.Model or myApp2.Model not as apps.myApp1.Model or apps.myApp2.Model
Also, specified AppConfig.
from django.apps import AppConfig
class AppOneConfig(AppConfig):
name = 'apps.myApp1'
verbose_name = 'My App One'
Is that expected ? I am pretty new to Django. Can anyone suggest what the mistake was?
Is that expected?
Yes, that is expected. By default, the app label uses the last part of the "python path". You can change it by specifying this in the AppConfig [Django-doc]. It is the .label attribute [Django-doc] of this AppConfig that determines the app label, and:
(…) It defaults to the last component of name. It should be a valid Python identifier. (…)
Now the .name attribute [Django-doc], and this is:
Full Python path to the application, e.g. 'django.contrib.admin'.
You can specify this by first specifying the AppConfig in the __init__.py file of your myApp1 directory:
# apps/myApp/__init__.py
default_app_config = 'apps.myApp.apps.App1Config'
then you make a file apps.py in the myApp1 directory, and write:
# apps/myApp/apps.py
from django.apps import AppConfig
class App1Config(AppConfig):
label = 'apps_myapp1'
Note: normally directories use slug_case, so I think it might be better to rename your myApp1 to myapp1 or my_app1.
EDIT: You thus need to set the label attribute of your AppOneConfig to:
class AppOneConfig(AppConfig):
name = 'apps.myApp1'
label = 'apps_myapp1'
verbose_name = 'My App One'

Customizing Django Admin's verbose_name by init, using default

As I would use in version 2 of django the
default_app_config = 'catalog.apps.CatalogConfig' in __init__ to set verbose_name and customize django admin? It returns the error
'No Module named catalog'
Details: I use my apps to a directory below and in INSTALLED_APPS I put projectName.AppName
Your question isn't much clear (to me). What I understood is, you tried to customize the admin interface by adding verbose_name and during that process you got the error, 'No Module named catalog'.
If that so,
Initial you have to put the verbose_name name in your apps configuration class inside the apps module
# catalog/apps.py
from django.apps import AppConfig
class CatalogConfig(AppConfig):
name = 'catalog'
verbose_name = 'Fantasy Title'
and in your INSTALLED_APPS of settings.py, it should be either
INSTALLED_APPS = [
'catalog',
.....
]
OR
INSTALLED_APPS = [
'catalog.apps.CatalogConfig',
.....
]

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.