2016-08-21 57 views
2

我想弄清楚如何在我的项目中避免依赖注入。应用程序目录中有一个文件notifications.py如何避免Django中的依赖注入?

文件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的,它无法导入SystemData

你知道该怎么办?

编辑:

stacktrace 

stacktrace

+0

你可以粘贴stacktrace吗?这可能就像在导入行用.models替换模型一样简单 – cdvv7788

+0

我在问题底部添加了堆栈跟踪 –

+0

我试图从模型中将SystemData替换为从.models导入SystemData并且它没有帮助。 。 –

回答

4

您可以使用内嵌进口解决功能循环依赖:

class SomeModel(models.Model): 
    .... 
    def save(...): 
     from .notifications import send_message_to_admin 
     send_message_to_admin('message') 

这将延迟import语句,直到函数实际上是执行,所以models模块已经被加载。然后notifications模块可以安全地导入models模块。

2

除了用圆形的进口,你可以做这样的:

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')