Heim  >  Artikel  >  Backend-Entwicklung  >  Ausführliche Erläuterung des rekursiven Python-Abfragemenüs und der Konvertierung in JSON-Beispielcode

Ausführliche Erläuterung des rekursiven Python-Abfragemenüs und der Konvertierung in JSON-Beispielcode

高洛峰
高洛峰Original
2017-03-28 09:16:252333Durchsuche

In diesem Artikel wird hauptsächlich das rekursive Abfragemenü von Python vorgestellt und in ein JSON-Beispiel umgewandelt. Interessierte Freunde können darauf verweisen.

Kürzlich musste ich ein Menü in Python schreiben, und es hat zwei oder drei Tage gedauert, bis ich es fertig hatte. Jetzt nehme ich es hier auf, und Freunde, die es brauchen, können daraus lernen.

Hinweis: Der Artikel zitiert den vollständigen nicht ausführbaren Code und stellt nur Auszüge aus den wichtigsten Teilen des Codes dar

Umgebung

  • Datenbank: MySQL

  • Python: 3.6

Tabellenstruktur


CREATE TABLE `tb_menu` (
 `id` varchar(32) NOT NULL COMMENT '唯一标识',
 `menu_name` varchar(40) DEFAULT NULL COMMENT '菜单名称',
 `menu_url` varchar(100) DEFAULT NULL COMMENT '菜单链接',
 `type` varchar(1) DEFAULT NULL COMMENT '类型',
 `parent` varchar(32) DEFAULT NULL COMMENT '父级目录id',
 `del_flag` varchar(1) NOT NULL DEFAULT '0' COMMENT '删除标志 0:不删除 1:已删除',
 `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
 `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
 PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='菜单表';

Python-Code

Im Menu-Objekt gibt es einen Verweis auf die Untermenüliste „subMenus“, der Typ ist list

Kerncode


def set_subMenus(id, menus):
  """
  根据传递过来的父菜单id,递归设置各层次父菜单的子菜单列表

  :param id: 父级id
  :param menus: 子菜单列表
  :return: 如果这个菜单没有子菜单,返回None;如果有子菜单,返回子菜单列表
  """
  # 记录子菜单列表
  subMenus = []
  # 遍历子菜单
  for m in menus:
    if m.parent == id:
      subMenus.append(m)

  # 把子菜单的子菜单再循环一遍
  for sub in subMenus:
    menus2 = queryByParent(sub.id)
    # 还有子菜单
    if len(menus):
      sub.subMenus = set_subMenus(sub.id, menus2)

  # 子菜单列表不为空
  if len(subMenus):
    return subMenus
  else: # 没有子菜单了
    return None

Testmethode


  def test_set_subMenus(self):
    # 一级菜单
    rootMenus = queryByParent('')
    for menu in rootMenus:
      subMenus = queryByParent(menu.id)
      menu.subMenus = set_subMenus(menu.id, subMenus)

Hinweis: Der grundlegende Prozess besteht darin, zuerst das Menü der ersten Ebene abzufragen und dann die ID des Menüs auf dieser Ebene und die Untermenüliste dieses Ebenenmenüs an die Methode set_subMenus zu übergeben, um die Menüs der unteren Ebene der Untermenüliste rekursiv festzulegen ;

unterstützt die Übergabe der Menü-ID, Abfrage aller Untermenüs unter diesem Menü. Wenn Sie ein Nullzeichen übergeben, beginnt die Abfrage im Stammverzeichnis

Im Objekt „rootMenus“ können Sie die vollständige Menübaumstruktur sehen

in Json konvertieren

Das ORM-Framework, das ich verwende, ist: sqlalchemy. Das direkt aus der Datenbank abgefragte Menüobjekt meldet einen Fehler, wenn es in Json konvertiert wird. Eine DTO-Klasse muss neu definiert werden, um das Menu-Objekt in ein Dto-Objekt zu konvertieren.

MenuDto


class MenuDto():
  def __init__(self, id, menu_name, menu_url, type, parent, subMenus):
    super().__init__()
    self.id = id
    self.menu_name = menu_name
    self.menu_url = menu_url
    self.type = type
    self.parent = parent
    self.subMenus = subMenus

  def __str__(self):
    return '%s(id=%s,menu_name=%s,menu_url=%s,type=%s,parent=%s)' % (
      self.__class__.__name__, self.id, self.menu_name, self.menu_url, self.type, self.parent)

  __repr = __str__

Die Methode zum rekursiven Festlegen von Untermenüs wird also neu definiert


def set_subMenuDtos(id, menuDtos):
  """
  根据传递过来的父菜单id,递归设置各层次父菜单的子菜单列表

  :param id: 父级id
  :param menuDtos: 子菜单列表
  :return: 如果这个菜单没有子菜单,返回None;如果有子菜单,返回子菜单列表
  """
  # 记录子菜单列表
  subMenuDtos = []
  # 遍历子菜单
  for m in menuDtos:
    m.name = to_pinyin(m.menu_name)
    if m.parent == id:
      subMenuDtos.append(m)

  # 把子菜单的子菜单再循环一遍
  for sub in subMenuDtos:
    menus2 = queryByParent(sub.id)
    menusDto2 = model_list_2_dto_list(menus2,
                     "MenuDto(id='', menu_name='', menu_url='', type='', parent='', subMenus='')")
    # 还有子菜单
    if len(menuDtos):
      if len(menusDto2):
        sub.subMenus = set_subMenuDtos(sub.id, menusDto2)
      else: # 没有子菜单,删除该节点
        sub.__delattr__('subMenus')

  # 子菜单列表不为空
  if len(subMenuDtos):
    return subMenuDtos
  else: # 没有子菜单了
    return None

Bemerkungen:

  1. Wenn ein Menü keine Untermenüs hat, löschen Sie das Attribut „subMenus“, sonst wird bei der Konvertierung in Json ein Nullwert angezeigt

  2. Die Methode „model_list_2_dto_list“ kann die Menüliste in die Liste „MenuDto“ konvertieren.

  3. to_pinyin ist eine Methode zum Konvertieren chinesischer Schriftzeichen in Pinyin. Hier müssen Sie nicht darauf achten.

Ansichtsebene gibt Json-Methode zurück


  def get(self):
    param = request.args
    id = param['id']
    # 如果id为空,查询的是从根目录开始的各级菜单
    rootMenus = queryByParent(id)
    rootMenuDtos = model_list_2_dto_list(rootMenus,
                       "MenuDto(id='', menu_name='', menu_url='', type='', parent='', subMenus='')")
    # 设置各级子菜单
    for menu in rootMenuDtos:
      menu.name = to_pinyin(menu.menu_name)
      subMenus = queryByParent(menu.id)
      if len(subMenus):
        subMenuDtos = model_list_2_dto_list(subMenus,
                          "MenuDto(id='', menu_name='', menu_url='', type='', parent='', subMenus='')")
        menu.subMenus = set_subMenuDtos(menu.id, subMenuDtos)
      else:
        menu.__delattr__('subMenus')

    menus_json = json.dumps(rootMenuDtos, default=lambda o: o.__dict__, sort_keys=True, allow_nan=false,
                skipkeys=true)
    # 需要转字典,否则返回的字符串会带有“\”
    menus_dict = json_dict(menus_json)
    return fullResponse(menus_dict)
fullResponse

from flask import jsonify


def fullResponse(data='', msg='', code=0):
  if msg == '':
    return jsonify({'code': code, 'data': data})
  elif data == '':
    return jsonify({'code': code, 'msg': msg})
  else:
    return jsonify({'code': code, 'msg': msg, 'data': data})

Hinweis: Die Bedeutung von JSON und Wörterbuch in Python ist ähnlich , am Ende Wenn json an die Seite zurückgegeben wird, müssen Sie es zuerst mit der Methode json_dict in den Dikttyp konvertieren, andernfalls enthält die zurückgegebene Zeichenfolge „“

Abfrageergebnisse

Ausführliche Erläuterung des rekursiven Python-Abfragemenüs und der Konvertierung in JSON-Beispielcode

Das obige ist der detaillierte Inhalt vonAusführliche Erläuterung des rekursiven Python-Abfragemenüs und der Konvertierung in JSON-Beispielcode. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn