# 博客项目 ### 昨日内容完善 - 密码加密存储 ```python from werkzeug.security import generate_password_hash, check_password_hash # 用户模型 class User(UserMixin, db.Model): id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(20), unique=True) password_hash = db.Column(db.String(128)) email = db.Column(db.String(32), unique=True) confirmed = db.Column(db.Boolean, default=False) @property def password(self): raise AttributeError(‘你想干啥,密码不可读‘) @password.setter def password(self, password): self.password_hash = generate_password_hash(password) # 密码校验 def verify_password(self, password): return check_password_hash(self.password_hash, password) ``` - 带有效期的token ```python from itsdangerous import TimedJSONWebSignatureSerializer as Serializer from itsdangerous import SignatureExpired, BadSignature @main.route(‘/generate/‘) def generate(): s = Serializer(current_app.config[‘SECRET_KEY‘], expires_in=10) token = s.dumps({‘id‘: 250}) return token @main.route(‘/check/<token>/‘) def check(token): s = Serializer(current_app.config[‘SECRET_KEY‘]) try: data = s.loads(token) except SignatureExpired as e: return ‘token已过期‘ except BadSignature as e: return ‘无效token‘ return str(data[‘id‘]) ``` ### 用户信息管理 - 用户详情 - 练习:修改密码、修改邮箱、找回密码 - 修改头像 - 添加点击跳转的逻辑 - 添加flask-uploads扩展 - 设计上传文件表单,创建并渲染 - 校验处理上传文件,保存图片 - 生成随机文件名 - 生成缩略图 - 将新的头像保存到数据库中 - 删除原来的头像文件 ### 博客管理 - 发表博客 - 设计博客模型,并且完成迁移 - 设计发表博客表单类,并创建渲染 - 提交后的校验(创建博客对象,保存到数据库) - 列表显示发表的博客(查询数据,分配到模板,然后遍历渲染) - 分页显示发表的博客(分页查询) ``` 方法:paginate,分页查询 参数: page:当前的页码 per_page:每页的条数 error_out:当查询出错时是否报错 返回值: Pagination:分页对象,包含了所有的分页信息 Pagination: 属性: page:当前页码 per_page:每页的条数,默认为20条 pages:总页数 total:总条数 prev_num:上一页的页码 next_num:下一页的页码 has_prev:是否有上一页 has_next:是否有下一页 items:当前页的数据 方法: iter_pages:返回一个迭代器,在分页导航条上显示的页码列表,显示不完的时返回None prev:上一页的分页对象 next:下一页的分页对象 ``` - 封装分页显示的宏 ```html {% macro show_pagination(pagination, endpoint) %} <nav aria-label="Page navigation"> <ul class="pagination"> {# 上一页 #} <li {% if not pagination.has_prev %}class="disabled"{% endif %}> <a href="{% if pagination.has_prev %}{{ url_for(endpoint, page=pagination.prev_num, **kwargs) }}{% else %}#{% endif %}" aria-label="Previous"> <span aria-hidden="true">«</span> </a> </li> {# 中间页码 #} {% for p in pagination.iter_pages() %} {% if p %} <li {% if pagination.page == p %}class="active"{% endif %}><a href="{{ url_for(endpoint, page=p, **kwargs) }}">{{ p }}</a></li> {% else %} <li><a href="#">…</a></li> {% endif %} {% endfor %} {# 下一页 #} <li {% if not pagination.has_next %}class="disabled"{% endif %}> <a href="{% if pagination.has_next %}{{ url_for(endpoint, page=pagination.next_num, **kwargs) }}{% else %}#{% endif %}" aria-label="Next"> <span aria-hidden="true">»</span> </a> </li> </ul> </nav> {% endmacro %} ``` ### 练习: - 点击用户头像或用户名,跳转到该用户发表的所有博客展示页码,显示不完分页展示 - 点击博客内容跳转到该篇博客的详情页面(博客信息、回复表单、所有回复(可以分页)) - 将导航条上的‘板块一‘改为‘我的发表‘
原文地址:https://www.cnblogs.com/liangliangzz/p/10222041.html
时间: 2024-10-08 17:24:25