WEB后端服务第9天
一、项目结构设计
apiserver
|---app
|---views
|--- __init__.py
|---models
|--- __init__.py
|---__init__.py
|---static
|---templates
|---utils
|---manage.py
在app的init.py脚本中,创建tornado.web.Application类对象,并且设置初始化的参数:
- handlers 设置路由与请求处理类的列表
- default_host 设置WEB服务的host名称或ip地址
- debug 设置是否为调试模式,True是调试, False是生产
- template_path 设置模板文件所在的路径
- static_path 设置静态资源所在的目录
- static_url_prefix 设置客户端请求静态资源的url前辍
- ui_modules 注册UI组件,是字典类型。
二、模板
支持jinja2的模板语言。
支持的语法:
-
填充 {{ 变量名 }}
-
表达式: 要求表达式必须符合Python语法的规则(支持Python合法语句)
- {{ 1+1 }}
- {{ ‘hello, disen’[-4:] }}
- {{ ‘,’.join([ str(x**2) for x in range(10) ]) }}
注意: 模板的变量不支持"点"语法,对于字典的key访问,应该是dict[key]访问
-
分支
-
{% if 条件表达式 %} html标签 {% end %}
-
{% if 条件表达式 %} html标签 {% else %} 标签 {% end %}
-
{% if 条件表达式 %} html标签 {% elif 条件 %} 标签 {% else %} 标签 {% end %}
-
循环
-
for 循环
{% for val in vals %} 标签 {{ val }} {% end %}
-
-
支持相关的函数:
- escape(val)
- json_encode(val)
- static_url() 生成静态资源的路径
-
支持"块"和替换
- {% block 名称 %} {% end %}
- {% extends "base.html " %}
-
支持UI组件化开发
-
定义UI组件
在app的包下创建ui包,将自定义UI组件类都在ui包下。
from tornado.web import UIModule class NavModule(UIModule): def render(self, menus): return self.render_string('ui/nav.html', menus=menus)
注意: 要在templates/ui目录下创建nav.html文件,内容如下:
<nav> <ul> {% for menu in menus %} <li>{{ menu }}</li> {% end %} </ul> </nav>
因为在nav.html模板文件中使用menus变量,所以在调用此UI组件时,需要传入menus。
-
注册UI组件
from app.ui.nav import NavModule settings = { 'debug': True, 'template_path': os.path.join(BASE_DIR, 'templates'), 'static_path': os.path.join(BASE_DIR, 'static'), 'static_url_prefix': '/s/', 'ui_modules': { 'Nav': NavModule } }
在Application初始化参数中使用"ui_modules"来注册UI组件,并设置UI组件名称,如Nav
-
使用UI组件
在index.html模板中使用,内容如下:
{% extends 'base.html' %} {% block nav %} {% module Nav(menus) %} {% end %}
{% module Nav(menus) %} 是引入UI组件。
-
中午默写
1. 获取url路径中的查询参数有哪些方式
- self.get_query_argument()
- self.get_query_arguments()
- self.get_argument()
- self.get_arguments()
- self.request.arguments.get()
- self.request.query_arguments.get()
2. 当请求被RequestHandler处理时,会调用哪此切入点函数
- initialize()
- prepare()
- on_finish()
- set_default_headers()
3. 如何删除客户端中cookie的token对象
- self.clear_cookie(‘token’)
三、 数据模型ORM
3.1 安装包
pip install sqlalchemy -i https://mirrors.aliyun.com
关于配置pip安装源的文件, 对于mac/linux系统中,在~/.pip/pip.conf, 配置内容:
[global]
index-url = https://mirrors.aliyun.com/pypi/simple
[install]
trusted-host = mirrors.aliyun.com
如果是在Window系统,在用户的目录的.pip子目录中,配置pip.ini 文件,内容同上。
3.2 配置
在utils包下,创建conn.py脚本,内容如下:
#!/usr/bin/python3
# coding: utf-8
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
engine = create_engine('mysql+pymysql://root:root@10.36.174.19:3306/edu?charset=utf8')
# 生成数据库连接的类
DbSession = sessionmaker(bind=engine)
# 创建会话类对象
session = DbSession()
# 生成所有模型类的父类
Base = declarative_base(bind=engine)
以面的code主要创建session会话连接和Base模型基类。
3.3 声明模型类
在app.models下创建menu.py脚本,声明Menu类
#!/usr/bin/python3
# coding: utf-8
from sqlalchemy import Column, Integer, String, Text, ForeignKey
from sqlalchemy.orm import relationship
from utils.conn import Base
class Menu(Base):
__tablename__ = 'menu'
id = Column(Integer, primary_key=True, autoincrement=True)
title = Column(String(20), unique=True, nullable=False)
url = Column(String(50),unique=True)
note = Column(Text)
parent_id = Column(Integer, ForeignKey('menu.id', name='parent_id_fk'),
default=0, server_default='0')
childs = relationship('Menu', backref='parent')
【注意】所有的模型类,必须声明" _tablename_ = ‘menu’" 表名
3.4 创建与删除表
在pycharm工具的Python console下导入Base类,并执行创建所有模型对应的表的函数
>>> from utils.conn import Base
>>> Base.metadata.create_all()
执行删除表的函数
>>> Base.metadata.drop_all()
3.5 CURD的实战
任务1要求: 实现菜单表的CURD操作。
任务2: 实现用户的管理、角色的管理、权限管理(用户、角色和菜单)
任务3: 实现用户登录,不同角色的用户登录之后,所看到的菜单是不同的。