簡體   English   中英

將“普通” Python類集成到Django模型類中

[英]Integration of 'normal' Python class into a Django models class

我編寫了一個具有許多類的Python應用程序。 假設其中一個是這樣的(過於簡單-但我嘗試表示功能的類型):

class PythonXyz(object):

    def __init__(self):
        self.x = []
        self.y = []
        self.z = []

    def append(self, x, y):
        self.x.append(x)
        self.y.append(y)

    def get_x(self):
        return self.x

    def get_y(self):
        return self.y

    def get_z(self):
        return self.x + self.y

    def size(self):
        return len(self.x)

    def dump(self):
        #generate some output

    def do_some_complex_stuff(self, q):
        #lots of calculations and manipulation of the self.x and self.y lists.

    def save(self, filename):
        #some code that saves data to disk

    def load(self, filename):
        #some code that loads data from disk

當該應用程序正常運行但缺乏可用性時,我決定放棄該應用程序,以便可以將瀏覽器用作窮人的GUI,也可以使用數據庫優勢。 所以我像這樣制作了一個model.py:

class DjangoXyzModel(models.model):
    x = models.FloatField()
    y = models.FloatField()

然后,我修改了PythonXYZ類中的load()和save()方法以使用數據庫而不是文件,並通過瀏覽器創建了一些視圖。

現在,我得到了3個Django應用程序,[edit]具有不同的數據庫模式[/ edit],每個應用程序都有其自己的models.py文件,其中包含多個模型類,此外,我的原始代碼還位於單獨的文件夾中。 我覺得這一切都變得很混亂,並讓我想到將所有PythonXyz方法完全集成到DjangoXyzModel類中的設計要簡潔得多,例如:

class DjangoXyzModel(models.model):
    x_db = models.FloatField()
    y_db = models.FloatField()

    def init_lists(self):
        self.x = []
        self.y = []
        self.z = []

    def append(self, x, y):
        self.x.append(x)
        self.y.append(y)

    def get_x(self):
        return self.x

    def get_y(self):
        return self.y

    def get_z(self):
        return self.x + self.y

    def size(self):
        return len(self.x)

    def dump(self):
        #generate some output

    def do_some_complex_stuff(self, q):
        #lots of calculations and manipulation of the self.x and self.y lists.

    def save_to_db(self):
        #some code that saves x,y lists to the database

    def load_from_db(self, filename):
        #some code that loads x,y lists from the database

我的問題是 :這種方法會被認為是Django模型類的“污染”,還是可以,只是個人喜好,還是這可能正是應該使用模型類的方式? 如果不建議或不贊成這樣做,哪種更好的方法來處理重復的類?

請注意,明顯的(?)解決方案完全擺脫列表並直接從數據庫工作是不可接受的,因為我需要將列表保存在內存中以便更快地訪問。 例如,列表一次從數據庫加載到內存中,並被訪問了數百或數千次。 每個列表可能大於1000個項目,因此,當需要一個值時(通常不是連續的),批量讀/寫也比單獨訪問要快得多。 此外,在最終將數據提交到數據庫之前,通常會對其進行多次修改。

聽起來您不應該將PythonXYZ類與Django模型集成。 讓Django管理數據庫(包含單獨的xy FloatField記錄)。 您的代碼處理實際上在管理Model實例集合的列表邏輯。 在Model上具有旨在在該個別Model實例的范圍之外的東西上運行的方法是沒有意義的。 您可能需要一個分為兩部分的解決方案-具有Collection類的Manager

為您的列表級加載/保存邏輯編寫一個自定義管理器 這比純粹的泛型類要好,因為它在概念上將列表操作與它們正在操作的數據庫記錄聯系在一起。 Manager將處理將Model實例的初始加載到這些x / y / z列表中,並將該列表保存回數據庫中。 從文檔中:

添加額外的Manager方法是向模型添加“表級”功能的首選方法。 (對於“行級”功能-即作用於模型對象的單個實例的功能-使用模型方法,而不是自定義Manager方法。)

自定義Manager方法可以返回您想要的任何內容。 它不必返回QuerySet。

由於列表本身聽起來像實體,因此您可能需要一個Collection類,該類為列表提供do_some_complex_stuff(),size(),dump()等方法。 這是您現在擁有的PythonXyz對象。 您可能可以對list進行子類化,以避免重新實現append()等。 Manager的load()可以返回此Collection類,而其save()會將Collection轉換為Model實例,以進行數據庫寫入。

至於在三個應用程序之間共享通用代碼。

  • 您可以使用抽象模型來保存包含具體應用程序模型的通用代碼。
  • 如果您需要在架構級別訪問通用性,請不要使用抽象的父模型。 (然后,您將有一個基表和單個表,其中僅包含特定於應用程序的列。)
  • 僅當您想要不同的行為並且架構相同/共享時,才使用代理模型。

將所有PythonXyz方法完全集成到DjangoXyzModel類中

別。 將基類分開,然后創建使用MI組合它們的模型代理 ,並在適當的地方覆蓋行為。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM