0

私はORMにかなり慣れていないので、Flaskアプリのメニューを作成するのに助けが必要です。モデルMenuItemを実装しました(srcは以下にあります)。

箇条書きは次のとおりです。

  • それはそれ自体と1対多の関係を持っています。
  • モデルと多対多の関係にありますRole

私の質問:

  1. generate_menu fnでアクセスできない子オブジェクトの削除をスキップできますか?このコード(再帰メソッドmark_restrictedの呼び出し)は複雑すぎるように見えますが、ORMクエリで実行できるのでしょうか?

  2. メニュー項目の順序付けを実装するためのベストプラクティスは何ですか?

Thxみんな!

class MenuItem(db.Model):
    """
    Menu item model

    """

    __tablename__ = 'sa_menu_item'

    id = db.Column(db.Integer, primary_key=True)
    parent_id = db.Column(db.Integer, db.ForeignKey('sa_menu_item.id'))    
    text = db.Column(db.String(100))
    view = db.Column(db.String(100))
    icon = db.Column(db.String(50))
    active = db.Column(db.Boolean)
    children = db.relationship('MenuItem')
    allowed_roles = db.relationship('Role',
                    secondary=menu_role
                    ,backref='menu_item')

    def __init__(self, text, view=None, icon=None):

        self.text = text
        self.view = view
        self.icon = icon

    def accessible_for(self, provided_set):

        for role in self.allowed_roles:
            if role.match(provided_set): return True
        return False

    def mark_restricted(self, lst, priv, not_allowed):
        """ Adds menu items restricted by priv to not_allowed list  """

        if not self.accessible_for(priv):
            if self in lst:
                not_allowed.append(lst.index(self))
            return

        if self.children is not None:
            for child in self.children:
                if not child.accessible_for(priv):
                    self.children.remove(child)
                else:
                    child.mark_restricted(lst, priv,not_allowed)

    @classmethod
    def generate_menu(cls, provided_set):
        """Generates menu based on provided_set of permissions""" 

        not_allowed = []

        lst = MenuItem.query.filter(MenuItem.parent_id == None, MenuItem.active == True, MenuItem.children != None).all()

        for item in lst:
            item.mark_restricted(lst,provided_set,not_allowed)

        lst = [i for j, i in enumerate(lst) if j not in not_allowed]

        return lst
4

1 に答える 1

0

order = db.Column(db.Integer)属性を追加し、generate_menu fnに次の行を追加することで、カスタムメニュー項目の順序付けを実装しました。

item.children.sort(key=operator.attrgetter('order'))
于 2012-06-30T19:15:40.650 に答える