I am relatively new to django, and trying to trigger a function on login. I have tested the function itself, and it works fine. The django-allauth login is also correctly configured. However, i cannot seem to trigger the signal below on login.
See code below... Any help would be appreciated...
pages/apps.py
from django.apps import AppConfig
class PagesConfig(AppConfig):
name = 'pages'
def ready(self):
import apps.pages.signals
pages/signals.py
from allauth.account.signals import user_logged_in
from django.dispatch.dispatcher import receiver
from django.utils import timezone
from datetime import timedelta
from .models import Token
#receiver(user_logged_in)
def user_logged_in_(request, user, **kwargs):
is_valid = Token.objects.filter(valid_until__gte=timezone.now() + timezone.timedelta(seconds=10800)).values()
if not is_valid:
new = Token(token='valid', valid_until=timezone.now())
else:
new = Token(token='not valid', valid_until=timezone.now())
new.save()
Managed to resolve this after much digging online...
You need to use the full python path to the application. This needs to be consistent with in settings.py, apps.py and init.py i.e.
settings.py
INSTALLED_APPS = ['dir.appname',]
apps.py
from django.apps import AppConfig
class AppnameConfig(AppConfig):
name = 'dir.appname'
def ready(self):
import dir.appname.signals
init.py
default_app_config = 'dir.appname.apps.AppnameConfig'
This following articles were useful in helping resolve the issue -
Django : Can't import 'module'. Check that module AppConfig.name is correct
How do I hook a django-allauth signal?
Related
I am trying to use signals for add and remove user from groups but I am not understanding where I am doing wrong. here is my code:
#receiver(post_save,sender=settings.AUTH_USER_MODEL)
def group(sender,instance,created,**kwargs):
group = Group.objects.get(name='myauthors')
if instance.is_blog_author == True:
instance.groups.add(group)
elif instance.is_blog_author == False:
instance.groups.remove(group)
create a signals.py file in your app
in your apps.py file,
overide the ready method of your appConfig class Like so
from django.apps import AppConfig
class MyAppClassConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = '<app_name>'
def ready(self):
from . import signals # import your signals here
init.py file of the app do this
default_app_config = '<app_name>.apps.MyAppClassConfig'
Then add your code to signals.py
Also show your model class and the error you are getting, i'm posting this answer based on assumptions.
#PS, I don't have enough reputation to post a comment hence using the answer box. such a shame.
I want to build an notification system in my django project. So I started to create an new app called notification. To create the notification I have to listen to the actions of the other models of my project. To reach this purpose I created in my notification app a signal handler :
in notification/signals.py
def create_subscription(sender, **kwargs):
pass
I connect this handler to my signal in my notification/apps.py
from django.apps import AppConfig
from django.db.models.signals import post_save
from notification.signals import create_subscription
from django.conf import settings
class NotificationConfig(AppConfig):
name = 'notification'
def ready(self):
post_save.connect(create_subscription, sender=settings.AUTH_USER_MODEL, dispatch_uid="create_subscription")
This works fine. I used my custom User model defined in my settings.
But whenever I want to use another model of my project, like :
from django.apps import AppConfig
from django.db.models.signals import post_save
from notification.signals import create_subscription
from member.models import Participation
class NotificationConfig(AppConfig):
name = 'notification'
def ready(self):
post_save.connect(create_subscription, sender=Participation, dispatch_uid="create_subscription")
I get an AppRegistryNotReady error, no matter which model I use.
I checked the order of declaration of my settings.INSTALLED_APPS, 'member' is declared before 'notification'.
When referring to the User model by passing threw the settings.AUTH_USER_MODEL it's working fine, but when referring directly to the model it creates an error.
Any ideas?
Although you can’t import models at the module-level where AppConfig classes are defined, you can import them in ready(), using either an import statement or get_model().
You need to do like
class NotificationConfig(AppConfig):
name = 'notification'
def ready(self):
from member.models import Participation
post_save.connect(create_subscription, sender=Participation, dispatch_uid="create_subscription")
For more info
I've made a django app, which is designed to be easily pluggable, and only has 1 view, and 1 model that project planning to use the app need to be aware of.
For ease, I'd like to just make the view and model available from the app-level. So rather than:
from mything.views import MyView
from mything.models import MyModel
You can instead just do:
from mything import MyView, MyModel
I changed the __init__.py file in the app to be like this:
from .views import MyView
from .models import MyModel
Of course I get the old django.core.exceptions.AppRegistryNotReady raised, since it's attempting to run the models.py code before the apps are loaded.
So I came up with the following workaround, and I'm wondering if it's a reasonable pattern to use or not. Now in __init__.py I have:
def _expose_items():
from .views import MyView
from .models import MyModel
globals()['MyView'] = MyView
globals()['MyModel'] = MyModel
And in my app's apps.py:
from . import _expose_items
class MyThingConfig(AppConfig):
name = 'mything'
def ready(self):
_expose_items()
So now indeed, I can directly import the view and model from the outside. Is this useful, or horrible?
Most Django apps do not collect views or models to the top level module. Refer to django.contrib.auth as an example.
Most Django apps do not collect views or models to the top level module. Use clear documentation to demonstrate how to import from your app. Hacks including globals() will probably create more trouble than help.
Refer to django.contrib.auth as an example.
in the mezzanine configuration docs, it says
NOTE If you are using Django 1.7 or greater and your app is included in your INSTALLED_APPS as an AppConfig (eg authors.apps.MyCrazyConfig), Mezzanine won’t import your defaults.py automatically. Instead you must import it manually in your AppConfig’s ready() method.
there are no examples showing how to do it, either on that page or in the django AppConfig.ready() page.
I created a theme/app.py :
from django.apps import AppConfig
from .defaults import *
class ThemeConfig(AppConfig):
name = 'theme'
verbose_name = "Theme"
def ready(self):
default
the theme/defaulty.py is thus:
from __future__ import unicode_literals
from django.utils.translation import ugettext_lazy as _
from mezzanine.conf import register_setting
register_setting(
name="TEMPLATE_ACCESSIBLE_SETTINGS",
append=True,
default=("SOCIAL_LINK_FACEBOOK",
"SOCIAL_LINK_TWITTER",
"SOCIAL_LINK_INSTAGRAM",
"SOCIAL_GOOGLE-PLUS",
),
register_setting(
name="SOCIAL_LINK_FACEBOOK",
label=_("Facebook link"),
description=_("If present a Facebook icon linking here will be in the "
"header."),
editable=True,
default="https://facebook.com/mezzatheme",
),
register_setting(
name="SOCIAL_LINK_TWITTER",
label=_("Facebook link"),
description=_("If present a Facebook icon linking here will be in the "
"header."),
editable=True,
default="https://twitter.com/",
),
how do i import default.py into appconfig.ready() method manually please?
Import your default in ready() method. See below.
from django.apps import AppConfig
class ThemeConfig(AppConfig):
name = 'theme'
verbose_name = "Theme"
def ready(self):
from .default import *
So far I have signals.py with following content:
from django.db.models.signals import post_delete, post_save
from django.core.signals import request_finished
from django.dispatch import receiver
from students.models import Student
#receiver(post_save, sender=Student)
def track_saved_objects(sender, **kwargs):
print 'i am here'
new_instance = kwargs['instance']
print new_instance
#receiver(request_finished)
def my_callback(sender, **kwargs):
print("Request finished!")
And I can not get why signals do not register and nothing happening with this code, nothing printed that means my signals are inactive
In docs I've found something about AppConfig.ready() but still can not get where else should I register my signals
As e-nouri said in the comments, this information is in the docs. If you scroll down from the Connecting Receiver Functions section to the "Where should this code live?" note, you'll see they should live in the AppConfig as you alluded to in your question.
In your application, you'll need to create an apps.py file if you don't have one created already. In it you'll define the config for your app. Here's an example that includes the signals registration.
from django.apps import AppConfig
class ExampleAppConfig(AppConfig):
name = 'example'
verbose_name = "Example Application"
def ready(self):
# To avoid putting the signals code in the __init__.py file or
# models.py file, we import the signals module here.
# https://docs.djangoproject.com/en/1.7/topics/signals/#connecting-receiver-functions
from example import signals