Я довольно новичок в ORM, поэтому мне нужна помощь в создании меню для моего приложения Flask. Я реализовал модель MenuItem (src ниже).Элементы меню элементов SQLAlchemy иерархия/упорядочение
пуля точки:
- Он имеет один-ко-многим с самим собой.
- Он имеет много-ко-многим с моделью
Role
Мои вопросы:
Могу ли я пропустить удаление без доступных дочерних объектов в generate_menu Fn? Этот код (вызов рекурсивного метода mark_restricted) выглядит слишком сложным, интересно, можно ли это сделать в запросе ORM?
Какова наилучшая практика для реализации заказа меню?
Thx guys!
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
Один запрос ORM будет переведен в один SQL запрос. Если вы считаете, что это можно сделать, почему бы вам не отправить SQL-запрос, который выполняет эту работу, и мы выясним, как это сделать из SA ORM. – van
Моим подходом было бы применить ограничение на атрибут роли объединенных таблиц. Я не настаиваю на том, чтобы делать # 1 через SQLAlchemy, меня больше интересовали лучшие практики SA. – 1osmi