'MyAppConfig' must supply a name attribute - python

i am try to run some piece of code when starting an apache server or django development server. I am using the AppConfig class to do this..(following the docs).
But while starting the server i am get the following error.
django.core.exceptions.ImproperlyConfigured: '{app_name}.apps.MyAppConfig' must supply a name attribute.
following is the sample code:
from django.apps import AppConfig
class MyAppConfig(AppConfig):
def ready():
#my stuff
I don't have any idea about the error.

The docs you linked to tell you what name should be:
AppConfig.name
Full Python path to the application, e.g. 'django.contrib.admin'.
This attribute defines which application the configuration applies to. It must be set in all AppConfig subclasses.
It must be unique across a Django project.
So if your app is call app_name, then you need to set name = 'app_name'.
from django.apps import AppConfig
class MyAppConfig(AppConfig):
name = 'app_name'
def ready(self):
# my stuff

Related

Automatically create django model instances at startup with empty database

My django project requires some model instances to be created at startup if they do not exist.
I currently create the required model instances I need in an app config.
class MyAppConfig(AppConfig):
name = 'my_app'
def ready(self):
create_required_objects()
def create_required_objects():
from my_app.models import MyObject
for name in MyObject.reserved_names:
if not MyObject.objects.filter(name=name).exists():
MyObject.objects.create(name=name, not_editable=True)
This works perfectly when the sqlite database is initialized, however if I clear the database and then try to run the sever, I get the following error:
django.db.utils.OperationalError: no such table: my_app_object
I would like to be able to clear the database (preferably by just removing db.sqlite3) and run the server.
Use post_migrate signal to create a new instance when migrating to the new database:
Like:
from django.db.models.signals import post_migrate
from my_app.models import MyObject
def create_required_objects(sender, **kwargs):
for name in MyObject.reserved_names:
if not MyObject.objects.filter(name=name).exists():
MyObject.objects.create(name=name, not_editable=True)
class MyAppConfig(AppConfig):
name = 'my_app'
def ready(self):
post_migrate.connect(create_required_objects ,sender=self)
This code automatically generates the user after migrating to the database.
You can use model_bakery to populate some temp data. You may need to do makemigrations and migrate to set up all tables in your database, you can follow this workflow.
python manage.py makemigrations
python manage.py migrate
In terms of populating data, you can try the following code:
from model_bakery import baker
from my_app.models import MyObject
baker.make(MyObject)
Add baker.make(MyObject) in your create_required_objects function after installation of model_bakery:
pip install model_bakery

How to override a package method in Django?

I'm trying to override a parent class method that I've installed via pip. But, the problem is that I'm not sure how my overridden class will be called so that it will use my method instead of parent class method. This is the method I'm trying to override:
class OIDCAuthenticationBackend(ModelBackend):
def verify_claims(self, claims):
"""Verify the provided claims to decide if authentication should be allowed."""
# Verify claims required by default configuration
scopes = self.get_settings('OIDC_RP_SCOPES', 'openid email')
if 'email' in scopes.split():
return 'email' in claims
LOGGER.warning('Custom OIDC_RP_SCOPES defined. '
'You need to override `verify_claims` for custom claims verification.')
return True
And my overridden method is :
models.py
from mozilla_django_oidc.auth import OIDCAuthenticationBackend
class MyOIDCAB(OIDCAuthenticationBackend):
def verify_claims(self, claims):
return True
I've written this on models.py according to some docs I read for overriding but I'm not sure where should I actually write this.
then trying to call it from my view functions like this:
views.py
from myapp import MyOIDCAB
but then I got this error:
from myapp import MyOIDCAB
ImportError: cannot import name 'MyOIDCAB'
I'm not sure I'm calling it in the right way or wrong?
My project structure is:
myproject
myapp
templates
manage.py
From the package site, they call it in the template like this:
Login
The class is in models.py file so here's how you should import that :
from myapp.models import MyOIDCAB

Where in Django can I run startup code that requires models?

On Django startup I need to run some code that requires access to the database. I prefer to do this via models.
Here's what I currently have in apps.py:
from django.apps import AppConfig
from .models import KnowledgeBase
class Pqawv1Config(AppConfig):
name = 'pqawV1'
def ready(self):
to_load = KnowledgeBase.objects.order_by('-timestamp').first()
# Here should go the file loading code
However, this gives the following exception:
django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet.
So is there a place in Django to run some startup code after the models are initialized?
The problem is that you import .models at the top of your file. This means that, when the file app.py file is loaded, Python will load the models.py file when it evalutes that line. But that is too early. You should let Django do the loading properly.
You can move the import in the def ready(self) method, such that the models.py file is imported when ready() is called by the Django framework, like:
from django.apps import AppConfig
class Pqawv1Config(AppConfig):
name = 'pqawV1'
def ready(self):
from .models import KnowledgeBase
to_load = KnowledgeBase.objects.order_by('-timestamp').first()
# Here should go the file loading code

Cannot import models from another app in Django

so I have 2 apps running in the same project.
My files are structured as follows:
/project_codebase
/project
__init.py
settings.py
urls.py
wsgi.py
...
/app1
...
/app2
...
manage.py
So, I for some weird reason have a different name for my base directory (that is, it ends with codebase). Hopefully, that is not an issue.
In my settings.py, I have this:
INSTALLED_APPS = [
...
'app1',
'app2',
]
Ok, so in my models.py (from app2), I can easily import models from app1 with from app1.models import *, however, when I use from app2.models import * in my models.py (from app1), I get an ImportError.
Any solutions to this?
This might be due to circular import issues. To avoid this you should load the model dynamically:
For recent versions of django (1.7+) use the application registry:
from django.apps import apps
MyModel1 = apps.get_model('app1', 'MyModel1')
For earlier django versions (<1.7):
from django.db.models.loading import get_model
MyModel1 = get_model('app1', 'MyModel1')
Note 1: If you want to define a ForeignKey relationship, there is no need for a separate import statement. Django has you covered on this:
If app1 is an installed app, you should define the ForeignKey relationship as follows:
# in app2.py
class MyModel2(models.Model):
mymodel1 = models.ForeignKey('app1.MyModel1')
Note 2: The get_model only works if app1 is an installed app and MyModel1 is the model you want to import from app1.
Note 3: Try to avoid wildcard import (from ... import *), as this is bad practice.
It's definitely a circular import.
But i think is what you need is to use models as some sort of RetationFields(ForeignKey, ManyToManyField or OneToOneField) arguments. So you need to skip import and use as so:
# app1/models.py
class Model1(models.Model):
relation_field = models.ForeignKey('app2.Model2')
From docs:
If you need to create a relationship on a model that has not yet been defined, you can use the name of the model, rather than the model object itself
To refer to models defined in another application, you can explicitly specify a model with the full application label
Just put str object as first argument to relation fields that leeds to <app_name>.<Model_name>.
Note: it's better to avoid importing everything from module(from <module_name> import *)
If you want to import only some specific module then do not use import *.
It will take more time load your all library and so can affect the speed of your app also.
If you want to use few modules from your second app then just add module name instead of whole libraries something like this:
from app2.models import Module1, Module2
or it may be circular import issue as other clarify.
Thanks.
i use this code always and it's work :)
from position_app.models import Member
You need to specify the model names you want to import, for ex from app1.models import ModelName1, ModelName2.
Make sure there is no name clash between one of your apps and one of the modules installed in your Python environment. If you use pip, you can run pip freezeto see a list of installed modules.
I had the same error when one of my apps was named 'packaging', and the packaging python module was installed.
I also face this problem when I try to import my model from another app in (django2.2)
But at last I Imported It and Its successfully working.
here is my two app:
INSTALLED_APPS = [
...
'categories',
'videos',
]
and this is the code for how I Imported it into videos/models.py file as a ForeignKey Connectivity
from django.db import models
class Videos(models.Model):
categories = models.ForeignKey('categories.Categories', related_name='categories', on_delete=models.CASCADE)
If want to see my Categories Model from categories/models.py file, you can check this code otherwise neglect it
from django.db import models
class Categories(models.Model):
category_name = models.CharField(max_length=50)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
It is a circular import
In my case I needed the imported class not for a relation field, but for use it inside a method instead.
If that's the case, I suggest to import inside the method, otherwise an AppRegistryNotReady("Models aren't loaded yet.") is raised.
class Student(CustomUser):
""" Usuario alumno """
class Meta:
verbose_name = "Alumno"
verbose_name_plural = "Alumnos"
def get_current_school_class(self):
""" Obtiene el curso actual de un alumno """
from school.models import SchoolClass, StudentClass
# proceed with the method...
it's not necessary to import models from others apps
just put the app.models in the foreignkey field and that's work ;)
app 1:
class model1(models.Model):
field=models.field type ...
app 2:
class model2(models.Model):
field=models.ForeignKey('app1.model1', on_delete. ...)
to avoid code correction :D

Model class doesn't declare an explicit app_label and either isn't in an application in

I use Django (1.8.1).
I need some python code to run at Django startup (apscheduler initialization), so in one of my project application, named for example my_app I created apps.py and declared appconfig ready method according to Django docs.
from apscheduler.schedulers.background import BackgroundScheduler
from django.apps import AppConfig
from my_app.views import some_shecheduled_method
class ManagerConfig(AppConfig):
name = 'my_app'
verbose_name = "My Application"
scheduler = None
def ready(self):
ManagerConfig.scheduler = BackgroundScheduler()
ManagerConfig.scheduler.add_job(some_shecheduled_method, 'interval', seconds=15)
ManagerConfig.scheduler.start()
Also in application __init__.py:
default_app_config = 'my_app.apps.ManagerConfig'
But after adding this to __init__.py in application log I see next message for all models in project:
05/04 16:00:25|py.warnings:116:WARNING ./authsystem/models.py:51: RemovedInDjango19Warning: Model class authsystem.models.UserActionLog doesn't declare an explicit app_label and either isn't in an application in INSTALLED_APPS or else was imported before its application was loaded. This will no longer be supported in Django 1.9.
class UserActionLog(Model):
Also when I use this apscheduler in Django it hangs sometimes when I reload application (I use uwsgi+py-autoreload=5), may be there are some mistakes in my approach and I need to use another way to initialize scheduler

Categories

Resources