2016-08-21 50 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')