Django / app import problem from submodule - django

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.

Related

ModuleNotFoundError: No module named 'foo'

I´m trying to make a cron inside my django app with django-crontab==0.7.1,.
Within my project settings installed apps, crontab app first, and then my app, both registered.
In my cron.py:
from .models import Url
urls=Url.objects.values_list('url')
def foo(url):
if url not in urls:
link= Url(
url=url,
)
link.save()
foo('https://example.org')
Also tried to put inside cron.py, but it doesn´t make sense since both are inside same app
from foo.models import Url
Also init.py inside app
My models.py inside foo app, after migrations ran
from django.db import models
class Url(models.Model):
url=models.URLField('url',blank=False,null=False)
but still getting ModuleNotFoundError: No module named 'foo'
Sorry if this has been asked before, but nothing watched yet gives me the answer
Thank you

Overriding the default admin site - can't find myproject

I am trying to override the default admin site. I followed the Django Docs here:
https://docs.djangoproject.com/en/3.0/ref/contrib/admin/#overriding-the-default-admin-site
I did everything as stated there so the files look like beneath:
admin/admin.py:
from django.contrib import admin
from django.utils.translation import gettext as _, gettext_lazy
class CustomAdminSite(admin.AdminSite):
# Text to put in each page's <h1>.
site_header = gettext_lazy('TEST administration')
admin/apps.py
from django.contrib.admin.apps import AdminConfig
class CustomAdminConfig(AdminConfig):
default_site = 'admin.CustomAdminSite'
core/urls.py
urlpatterns = [
path(r'testadmin/', admin.site.urls),
]
core/settings.py
INSTALLED_APPS = [
'admin.apps.CustomAdminConfig',
]
Now I am getting a ImportError:
ImportError: Module "admin" does not define a "CustomAdminSite" attribute/class
I think this is because django is looking for a admin module that lives inside of the virtual environment with the CustomAdminSite class. This is not the case, the admin folder with the necessary python files lives in the base path of myproject. When I state this in my settings like: myproject.admin.apps.CustomAdminConfig I am getting a ModuleNotFOundError:
ModuleNotFoundError: No module named 'myproject'
I guess the same thing as stated above. Django is looking for a module named myproject inside of the virtual environment.
Is there a way to change this in the settings or a way to bypass this some other way?
As #IainShelvington said, the name of the module is likely admin.admin, since admin is the name of the app, and then in that app you have a "submodule" named admin, so this should be:
from django.contrib.admin.apps import AdminConfig
class CustomAdminConfig(AdminConfig):
default_site = 'admin.admin.CustomAdminSite'

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

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.

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.