如何避免 Django 中的依赖注入?
How to avoid dependency injection in Django?
我正在尝试弄清楚如何避免在我的项目中进行依赖注入。应用程序目录中有一个文件 notifications.py
。
文件notifications.py
包含向管理员和用户发送电子邮件的方法。要获得管理员电子邮件,我需要检查 SystemData
模型的对象。但在模型中,我使用通知。
型号
class SystemData(models.Model):
admin_alerts_email = models.EmailField(verbose_name=u'Emailová adresa admina')
contact_us_email = models.EmailField(verbose_name=u'Adresa kontaktujte nás')
waiting_threshold = models.PositiveSmallIntegerField(verbose_name=u'Maximálny počet minút čakania')
class SomeModel(models.Model):
....
def save(...):
notifications.send_message_to_admin('message')
notifications.py
from django.core.mail import EmailMessage
from models import SystemData
def send_message_to_admin(message):
mail = EmailMessage(subject, message, to=[SystemData.objects.all().first().admin_email])
mail.send()
Django returns 无法导入 SystemData
.
你知道要做什么吗?
编辑:
stacktrace
您可以使用内联导入解决函数中的循环依赖:
class SomeModel(models.Model):
....
def save(...):
from .notifications import send_message_to_admin
send_message_to_admin('message')
这会延迟 import 语句直到函数真正执行,所以 models
模块已经被加载。然后 notifications
模块可以安全地导入 models
模块。
除了使用循环导入之外,您还可以这样做:
from django.core.mail import EmailMessage
from django.db.models.signals import post_save
from django.dispatch import receiver
from .models import SystemData, SomeModel
@receiver(post_save, sender=SomeModel)
def send_message_to_admin(sender, instance, created, **kwargs):
message = 'message'
mail = EmailMessage(
subject,
message,
to=[SystemData.objects.all().first().admin_email]
)
mail.send()
并在 models.py 的末尾放置
from .notifications import *
或使用 AppConfig 的最新方法来注册信号(这就是您的通知实际所做的)
参见:https://chriskief.com/2014/02/28/django-1-7-signals-appconfig/
这样它会在应用程序注册表准备就绪时加载,您将避免循环导入,因此该行:
from .notifications import *
可以从 models.py
中删除
AppConfig 可以以更通用的方式使用,还允许您导入这样的模型:
from django.apps import apps
Model = apps.get_model('app_name', 'Model')
我正在尝试弄清楚如何避免在我的项目中进行依赖注入。应用程序目录中有一个文件 notifications.py
。
文件notifications.py
包含向管理员和用户发送电子邮件的方法。要获得管理员电子邮件,我需要检查 SystemData
模型的对象。但在模型中,我使用通知。
型号
class SystemData(models.Model):
admin_alerts_email = models.EmailField(verbose_name=u'Emailová adresa admina')
contact_us_email = models.EmailField(verbose_name=u'Adresa kontaktujte nás')
waiting_threshold = models.PositiveSmallIntegerField(verbose_name=u'Maximálny počet minút čakania')
class SomeModel(models.Model):
....
def save(...):
notifications.send_message_to_admin('message')
notifications.py
from django.core.mail import EmailMessage
from models import SystemData
def send_message_to_admin(message):
mail = EmailMessage(subject, message, to=[SystemData.objects.all().first().admin_email])
mail.send()
Django returns 无法导入 SystemData
.
你知道要做什么吗?
编辑:
stacktrace
您可以使用内联导入解决函数中的循环依赖:
class SomeModel(models.Model):
....
def save(...):
from .notifications import send_message_to_admin
send_message_to_admin('message')
这会延迟 import 语句直到函数真正执行,所以 models
模块已经被加载。然后 notifications
模块可以安全地导入 models
模块。
除了使用循环导入之外,您还可以这样做:
from django.core.mail import EmailMessage
from django.db.models.signals import post_save
from django.dispatch import receiver
from .models import SystemData, SomeModel
@receiver(post_save, sender=SomeModel)
def send_message_to_admin(sender, instance, created, **kwargs):
message = 'message'
mail = EmailMessage(
subject,
message,
to=[SystemData.objects.all().first().admin_email]
)
mail.send()
并在 models.py 的末尾放置
from .notifications import *
或使用 AppConfig 的最新方法来注册信号(这就是您的通知实际所做的)
参见:https://chriskief.com/2014/02/28/django-1-7-signals-appconfig/
这样它会在应用程序注册表准备就绪时加载,您将避免循环导入,因此该行:
from .notifications import *
可以从 models.py
中删除AppConfig 可以以更通用的方式使用,还允许您导入这样的模型:
from django.apps import apps
Model = apps.get_model('app_name', 'Model')