2012-07-07 43 views
0

您不需要閱讀所有這篇文章以幫助我回答問題,本文的其餘部分僅僅是問題出現的上下文,但一般問題是:何處放置商業邏輯,跨越Django中的多個模型

在哪裏把商業邏輯,跨越多個模型在Django?

一些posibilites:

  • 一些視圖? (我不這麼認爲,它必須在管理和若干意見的工作,DRY)
  • 模型/表格保存方法是什麼?(如何?)
  • 清潔methos模型/表格?(如何?)
  • 拆分邏輯和使用信號?(如何?)
  • 其他?

語境:

我有這個型號:

  1. 部:在公司引用不同的部門(風險,金融,IT,...)
  2. 員工:五月一段時間只屬於一個部門,然後更換爲其他部門。
  3. 項目:每個部門可以有多個項目,一個項目屬於多個部門。
  4. 成員:員工和部門多對多的關係,其中包括其他領域,如join_date和leave_date之間的中間表,重要的領域是FK:部門,FK:員工
  5. 歷史:成員和項目之間的中間表,讓我知道哪個員工參與了他在某個部門工作的願望項目,重要的領域是fk:會員,fk:項目。
  6. CurrentProjects:當前將部門與其正在處理的項目相關聯的表。

supose我在Django管理員,我去部門風險,風險目前Proyect1和Project2簽署。當我添加一個新員工「JHON史密斯」(例如,使用系內聯形式),然後按保存按鈕,我想要的模型歷史被用該信息更新:

 
Membership table (only important fields): 

pk Department Employee  join_date leave_date 
20 Risk   Jhon Smith xxxx  xxxx 


History Table (only important fields): 

Membership Project 
20   Project1 
20   project2 

我的意思是,當一個新的員工被分配到一個新的部門,該部門的所有實際項目必須被分配到表歷史記錄中的該成員資格員工部門。

問題是在Django中放置這個邏輯的地方?你可以看到這個邏輯涉及倍數的機型,有些posibilities是:

  • 在一些視圖(我不這麼認爲,它必須在管理interfase和在其他地方工作)
  • 在的清潔方法會員,部門或員工模型/表單?
  • 在會員,部門或員工模型/表單的保存方法中?
  • 我必須拆分邏輯並使用類似信號的東西嗎? (一些例子?)
  • 其他?
  • 我過了複雜的永恆? =)

注意事項:如果代碼可能在進程中的任意位置生成valueerror並且用戶/管理員能夠以無界形式查看此錯誤,那將會很好。

謝謝

+0

您是否探索過信號? – jdi 2012-07-07 21:37:17

+0

@jdi我現在正在審查這個主題,但是你對如何在這種情況下使用它們有一些見解嗎? – javier 2012-07-07 21:52:53

+0

看到我的答案。我談論這個。 – jdi 2012-07-07 22:07:31

回答

3

我只是評論邏輯應該在哪裏生活的方面。這一切聽起來都像我的模型邏輯。 Django的MVC概念稍有混淆。當它純粹的數據關係我相信它的所有模型邏輯。我建議將這些方法儘可能接近它們所影響的模型,並簡單地從觸發模型中調用最小的調用。

如果你非常關心解耦應用程序,那麼你可以使用信號。取而代之的是,模型A知道它需要在保存期間調用XYZ,它會以另一種方式進行。模型A只是發出一個信號。 XYZ將負責連接到信號。你甚至可以在一個完全一般的項目應用程序中製作你的信號定義,在這種情況下,觸發或接收模型都不知道其他人的行爲。它只是綁定他們。

有一些內置信號,例如之前和after a save在模型上,這意味着如果你正在尋找一個保存觸發器,你將不必發出一些自定義。但讓我們說在一個模型邏輯的不同點上,你需要發出一個自定義信號,比如「Name changed」,你可以發出你自己的信號。

模型A

import django.dispatch 

name_changed = django.dispatch.Signal(providing_args=["name"]) 

class ModelA: 
    ... 

    def foo: 
     # something happened here 
     name_changed.send(sender=self, name=the_name) 

模型B,C,d

from myApp.modelA import name_changed 

name_changed.connect(modelB.handle_name_change, dispatch_uid="my_unique_identifier") 
name_changed.connect(modelC.handle_name_change, dispatch_uid="my_unique_identifier") 
name_changed.connect(modelD.handle_name_change, dispatch_uid="my_unique_identifier") 

我個人有用於需要一些一般的應用程序創建utils.py模塊的習慣「控制器模型「邏輯。他們更像是行動或助手。

+0

感謝您的回答,我現在試圖使用這種方法,但我仍然懷疑是否有更好的方法,所以我會繼續研究和發佈,而且,我對你的utils.py文件很感興趣,你有什麼樣的代碼? =) – javier 2012-07-07 22:20:01

+0

@javier:utils只是可能像'do_something_with_something'這樣的函數。基本上,我只是試圖將重邏輯的數量保持在模型之外,並將其限制爲簡單的拉取和表示數據的方式。我真的不會在正確或錯誤的地方加入代碼。當您設計一個應用程序時,信號通常會很有用,該應用程序應該被分配並用於任何其他項目。您允許項目所有者連接到您的應用程序的信號。但是如果你正在設計你自己的項目,那麼從一個應用程序導入另一個應用程序並使用邏輯就沒有什麼壞處。 – jdi 2012-07-07 22:39:53

+0

+1用於放置utils.py – Soask 2012-07-19 15:53:27

0

也許問題是你在那裏有「歷史」表。我不知道您的Project表中有什麼樣的信息。但是,如果每個項目都有開始和結束日期,那麼您的歷史記錄表格正在處理重複信息。在這種情況下,如果您想知道在哪個項目中工作過的員工,您只需要知道該員工爲該部門工作過多少日期,然後您需要找到該部門之間開發的項目之前的日期範圍。

我希望你能理解我的觀點。如果不是,請告訴我,這樣我可以更好地解釋它(也許有一個例子)。

但正如我理解你,你的模型,我認爲你不需要歷史表。它會複製信息...

因此,如果您的Project模型具有此信息(日期範圍),解決方案應該存在於管理器中,因爲它只是查找您希望生活在多個表中的信息...

希望它能幫助!

+0

感謝您的回答,我理解您的觀點,但事實是,邏輯比這更復雜一點,日期不僅僅是可靠的實際項目表,但即使日期是可靠的,我想知道哪裏是最好的地方把這種商業邏輯,跨越多個模型。 – javier 2012-07-07 22:01:43

+0

我認爲答案在模型中。我不會更改模型的保存方法,因爲我認爲它應該是一個愚蠢的方法,只是爲了管理該模型/對象的數據庫問題。所以,我認爲它應該是一種表單保存方法,因爲它涉及多個模型來保存。如果你想控制一切都是一致的,你可以將這個邏輯添加到表單清理方法中。 – marianobianchi 2012-07-07 22:11:00

+0

@marianobibanchi我試圖理解你的評論,你是否在提出跨越多個模型的商業邏輯必須從這些模型的形式來管理?如果我必須爲同一模型加上其他api和django管理員的多種表單,您對DRY原則有什麼看法? – javier 2012-07-07 22:25:41