2012-06-30 4 views
0

나는 ORM에 익숙하지 않으므로 Flask 응용 프로그램의 메뉴를 만드는 데 도움이 필요합니다. 모델 MenuItem (src는 아래)을 구현했습니다.SQLAlchemy 메뉴 항목 계층 구조/주문

총알 포인트는 그 자체로 일대 다 관계가

  • .
  • 그것은이 다 대다 모델 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 
+0

한 ORM 쿼리를 하나 개의 SQL 쿼리로 변환됩니다. 이 작업을 수행 할 수 있다고 생각되면 작업을 수행하는 SQL 쿼리를 게시하지 않는 것이 좋습니다. 우리는 SA ORM에서이를 작성하는 방법을 알아낼 것입니다. – van

+0

내 접근 방식은 조인 된 테이블 (들)의 역할 특성에 대한 제한을 적용하는 것입니다. SQLAlchemy를 통해 # 1을 수행한다고 주장하지는 않습니다. SA 베스트 프랙티스에 더 관심이있었습니다. – 1osmi

답변

0

내가 추가 속성 order = db.Column(db.Integer)을 추가하고 FN generate_menu에 다음 줄을 추가하여 사용자 정의 메뉴 항목 순서 구현 :

item.children.sort(key=operator.attrgetter('order'))