Importing default.py manually into AppConfig ready () method - python

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 *

Related

Make models in admin site appear only in debug mode otherwise display one model

I want to make my models appear in admin site only when debug variable is set to True, when debug is set to False I only want to display one model
I am looking for an elegant way to implement this
I thought I could do something like this:
if not DEBUG:
admin.site._registry = {}
admin.site.register(Model 1)
But where does this code should live? I want it to execute after execution of all admin.py modules from all applications where models registration takes place.
To sum it up
DEBUG = TRUE
Admin site shows:
Model 1
Model 2
Model 3
DEBUG = FALSE
Admin site shows:
Model 1
You can override one of the ready methods of an AppConfig of any app. For example if you have an app named app_name, we can implement an AppConfig that looks like:
# app_name/apps.py
from django.apps import AppConfig
class AppNameConfig(AppConfig):
name = 'app_name'
def ready(self):
from app_name.models import SomeModel
from django.conf import settings
if not settings.DEBUG:
from django.contrib import admin
for cls in list(admin.site._registry):
if cls is not SomeName:
admin.site.unregister(cls)
return super().ready()
with the SomeModel the model you wish to retain.

django-allauth signals user_signed_in signal isn't working

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?

How to customize oscar address form fields?

after customizing django oscar app (address) and adding a new field named 'area' when I run migrate it gave me Unknown field(s) (area) specified for UserAddress
I used the command
./manage.py oscar_fork_app address myappsfolder/
after creating the folder and __init__.py file in it
then I started to customize the app like this:
#myappsfolder/address/models.py
from django.db import models
from django.conf import settings
from django.utils.translation import ugettext_lazy as _
from oscar.apps.address.abstract_models import AbstractAddress
class Address(AbstractAddress):
area = models.CharField(_("Area"), max_length=120,
choices=settings.AREA_CHOICES, blank=True)
from oscar.apps.address.models import *
#myappsfolder/address/forms.py
from oscar.apps.address import forms as base_forms
class UserAddressForm(base_forms.UserAddressForm):
class Meta(base_forms.UserAddressForm.Meta):
fields = ['area']
I didn't touch the admin.py , config.py and __init__.py that have been created by the command ./manage.py oscar_fork_app address myappsfolder/
also the __init__.py that I created in myappsfolder is empty, should I add something to these files ?
What should I do to customize this app ? or any other app ?
If I edited the models in oscar/apps/address/abstract_models.py it only apply in local host and the error in forms disappear , which means that django still reading the models from oscar/apps not from myappsfolder.
You cannot override AbstractAddress in that way because the changes will not propagate to other models such as UserAddress that directly subclass AbstractAddress. Instead you need to override the specific address models that you want to change. So if you want to change UserAddress then override that particular model:
from oscar.apps.address.abstract_models import AbstractUserAddress
class UserAddress(AbstractUserAddress):
area = models.CharField(_("Area"), max_length=120, choices=settings.AREA_CHOICES, blank=True)
... after which your changes to UserAddressForm should work.
If you need to override ShippingAddress as well, then you will also have to fork the shipping app and do the same thing there, because that is where the model lives.

Django : An AppRegistryNotReady raised error when trying to connect a signal between different apps

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

Expose a Django app's models at the module level

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.

Categories