博客项目续

# 博客项目

### 昨日内容完善

- 密码加密存储

  ```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">&laquo;</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="#">&hellip;</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">&raquo;</span>
                  </a>
              </li>
          </ul>
      </nav>
  {% endmacro %}
  ```

### 练习:

- 点击用户头像或用户名,跳转到该用户发表的所有博客展示页码,显示不完分页展示
- 点击博客内容跳转到该篇博客的详情页面(博客信息、回复表单、所有回复(可以分页))
- 将导航条上的'板块一'改为'我的发表'

 

posted @ 2019-01-04 19:24  青春叛逆者  阅读(114)  评论(0编辑  收藏  举报