在ModelViewController模式中使用ObjectListView和Python中的SQLAlchemy

2024-04-16 19:47:04 发布

您现在位置:Python中文网/ 问答频道 /正文

我考虑如何使用ObjectListViewModel-View-Controller Pattern与wxPython&SQLAlchemy相匹配。我不确定,所以我创建了一个简单的例子作为工作基础,而不是解决方案。在

与下面代码相关的具体问题是:如果生成一个新的MyData对象,会发生什么?在

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import wx
import sqlalchemy as sa
import sqlalchemy.ext.declarative as sad
import ObjectListView as olv

_Base = sad.declarative_base()

class MyData(_Base):
    """the database table representing class"""
    __tablename__ = 'MyData'

    __name = sa.Column('name', sa.String, primary_key=True)
    __count = sa.Column('count', sa.Numeric(10, 2))

    def __init__(self, name, count):
        super(MyData, self).__init__()
        self.__name = name
        self.__count = count

    def GetName(self):
        return self.__name

    def GetCount(self):
        return self.__count


def CreateData():
    """
        helper creating data

        imagnine this as a SELECT * FROM on the database
    """
    return [
        MyData('Anna', 7),
        MyData('Bana', 6)
        ]


class MyView(olv.ObjectListView):
    def __init__(self, parent):
        super(MyView, self).__init__(parent, wx.ID_ANY, style=wx.LC_REPORT)
        self.SetColumns([
            olv.ColumnDefn('Name', valueGetter='GetName'),
            olv.ColumnDefn('Count', valueGetter='GetCount')
            ])
        data = CreateData()
        self.SetObjects(data)


    def ColDef(self):
        return 

class MyApp(wx.App):
    def OnInit(self):
        frame = wx.Frame(None)
        view = MyView(frame)
        frame.Show()
        return True


if __name__ == '__main__':
    app = MyApp()
    app.MainLoop()

你怎么想。。。 创建一个控制器“MyDataController”来处理MyData对象的所有sqlalchemy内容。e、 g.GetAllMyDataObjects AddMyDataObjectToDatabase,QueryMyData。。。 与观察者模式相关的ObjectListView观察者作为主体的控制器。 我不确定这是否是一个优雅的解决方案。 关键是混淆了什么是模型?一个(和新的)MyData实例还是所有MyData实例的列表?没有一个智能列表可以像一个模型。在


Tags: nameimportselfreturnsqlalchemyinitdefas
1条回答
网友
1楼 · 发布于 2024-04-16 19:47:04

关于OLV。在我的例子中,当对SA模型进行更新时,我使用pubsub通知全世界关于添加/更新/删除的更改。在

然后,我的OLV基类订阅“itemAdded”、“itemModified”和“itemDeleted”消息,并调用以下方法:

def pubListItemAdded(self, dbitem):
    """
    Add list if dbitem instance matches dbScKlass

    :param dbitem: an SA model instance

    If dbitem instance matches the list controls model it is added.
    """
    # protect from PyDeadObjectError
    if self:
        # E.g. Externalimp is a faked class and does not exist in db
        # so we need to protect for that
        if hasattr(db, self._klassName):
            tList = self.getList()
            cInst = getattr(db, self._klassName)
            if isinstance(dbitem, cInst):
                log.debug("olvbase - added: %s", dbitem)
                log.debug("olvbase - added: %s", self)
                # for some reason this creates dups on e.g. rating/tasting/consumption
                # so, lets check if it is there and only add if not
                idx = tList.GetIndexOf(dbitem)
                if idx == -1:
                    tList.AddObject(dbitem)
                else:
                    tList.RefreshObject(dbitem)

                # bring it into view
                self.resetSelection()
                tList.SelectObject(dbitem, deselectOthers=True,
                                   ensureVisible=True)

def pubListItemModified(self, dbitem):
    """
    Update list if dbitem instance matches dbScKlass

    :param dbitem: an SA model instance

    If dbitem instance matches the list controls model it is updated.
    """
    # protect from PyDeadObjectError
    if self:
        # E.g. Externalimp is a faked class and does not exist in db
        # so we need to protect for that
        if hasattr(db, self._klassName):
            cInst = getattr(db, self._klassName)
            if isinstance(dbitem, cInst):
                log.debug("olvbase - modified: %s", dbitem)
                log.debug("olvbase - modified: %s", self)
                tList = self.getList()
                # need to refresh to ensure relations are loaded
                wx.GetApp().ds.refresh(dbitem)
                tList.RefreshObject(dbitem)
                tList.SelectObject(dbitem, deselectOthers=True,
                                    ensureVisible=True)
                # deselect all, so if we select same item again
                # we will get a select event
                tList.DeselectAll()

def pubListItemDeleted(self, dbitem):
    """
    Delete from list if dbitem instance matches dbScKlass

    :param dbitem: an SA model instance

    If dbitem instance matches the list controls model it is updated.
    """
    # protect from PyDeadObjectError
    if self:
        # E.g. Externalimp is a faked class and does not exist in db
        # so we need to protect for that
        if hasattr(db, self._klassName):
            cInst = getattr(db, self._klassName)
            if isinstance(dbitem, cInst):
                log.debug("olvbase - deleted: %s", dbitem)
                log.debug("olvbase - deleted: %s", self)
                tList = self.getList()
                tList.RemoveObject(dbitem)
                self.currentObject = None
                self.currentItemPkey = None

相关问题 更多 >