美文网首页我爱编程
慕课网 python微电影项目 小知识点整理

慕课网 python微电影项目 小知识点整理

作者: 普度众生的面瘫青年 | 来源:发表于2018-04-06 19:08 被阅读138次

    项目视频下载地址

    链接: https://pan.baidu.com/s/11ROsvoKukAUAiEnztvS55A 密码: qsj2

    项目代码github地址

    链接: https://github.com/cafeUncle/movie-mooc.git

    mysql命令

    mysql命令行下,\s命令可以查看简单信息


    pip操作

    pip 下载时如果很慢,可以使用-i命令指定下载源 使用--trusted-host指定信任的主机
    pip install -i http://pypi.douban.com/simple/ --trustrt-host pypi.douban.com virtualenv


    pip description
    freeze Output installed packages in requirements format.
    list List installed packages.

    pip安装包的方式中,有如下两种安装方式:

    pip install flask
    pip install -r requirements.txt
    
    • 文件requirement.txt里面内容的格式和pip freeze的格式完全一样。因此我们可以将pip freeze的内容输出至requirements.txt。其他机器可以根据导出的requirements.txt进行包安装。
    pip freeze > requirements.txt # 输出本地包环境至文件
    pip install -r requirements.txt # 根据文件进行包安装
    
    • pip freeze 为什么比 pip list 的包少几个呢?
      因为pip , wheel , setuptools 等包,是自带的而无法(un)install的。考虑到pip freeze的用途,所以这些包并没有显示。
      如果一定要用pip freeze来显示所有包,可以加上参数-all,即pip freeze -all

    蓝图

    flask blueprint

    1. 定义蓝图
      app/admin/__init__.py
      from flask import Blueprint
      admin = Blueprint('admin', name)
      import views
    2. 调用蓝图
      app/admin/views.py
      from . import admin
      @admin.route("/")
    3. 注册蓝图
      app/__init__.py
      from flask import admin as admin_blueprint
      app.register_blueprint(admin_blueprint, url_prefix="/admin")
      必须先调用蓝图设置好路由,然后再注册蓝图

    前台布局搭建

    1. 静态文件引入: {{ url_for('static', filename='文件路径') }}
    2. 定义路由: {{ url_for('模块名.视图名',变量=参数) }}
      模块名.视图名对应view.py中的方法名,而不是html文件名,个人认为写"/login"这样的路径更方便,学到后面如果发现url_for的特别用法,再来更新
    3. 定义数据块: {% block 数据块名称 %} ... {% endblock %}
      一般定义在base页面中,类似freemarker中的macro,可以在子模板中引用同名block块。
    1. 一般首先定义一个base模板,在内容中允许定义多个block块,由子模板引用,子模板决定替换哪些block块,没有定义的块即不替换,直接使用父模板的block块 。
    1. 通过{{ block.super }},可以引用上级代码块并在其基础上进行一些修改
    {% block name%}
        {{ block.super }}
        <p>...
    {% endblock %}
    
    1. 引用时首先要在子模板中{% extends "base.html" %}

    extends只能写在子模板第一行,参数一般为字符串,也可为变量,可带路径或相对路径,以TEMPLATE_DIRS的模板目录为基准

    1. 其它
    1. {% include 'includes/nav.html' %}

    可带路径或相对路径,以TEMPLATE_DIRS的模板目录为基准
    也可以使用变量名 {% include template_name %},包含的变量都会统一处理,不区分是第几层模板
    被包含在(include)的页面里面不能用{%block%},类似jsp的静态导入<%@ include file="fileurl" %>和动态导入<jsp:include page="menu.jsp"/>的区别

    1. {% import 'ui/page_admin.html' as pg %}

    引用后可以使用别名调用。
    page_admin.html 内容如下,类似freemarker的macro

    {% macro page(data, url) %}
    {% if data %}
    <ul class="pagination pagination-sm no-margin pull-right">
        <li><a href="{{url_for(url, page=1)}}">首页</a></li>
    
        {% if data.has_prev %}
        <li><a href="{{url_for(url, page=data.prev_num)}}">上一页</a></li>
        {% else %}
        <li><a class="disabled">上一页</a></li>
        {% endif %}
    
        {% for v in data.iter_pages() %}
        {% if v == data.page %}
        <li class="active"><a href="#">{{ v }}</a></li>
        {% else %}
        <li><a href="{{url_for(url, page=v)}}">{{ v }}</a></li>
        {% endif %}
        {% endfor %}
    
        {% if data.has_next %}
        <li><a href="{{url_for(url, page=data.next_num)}}">下一页</a></li>
        {% else %}
        <li><a class="disabled">下一页</a></li>
        {% endif %}
        <li><a href="{{url_for(url, page=data.pages)}}">尾页</a></li>
    </ul>
    {% endif %}
    {%- endmacro %}
    

    调用时

    <div class="box-footer clearfix">
            {{ pg.page(page_data, 'admin.tag_list') }}
    </div>
    
    1. {% for x in range(1,5)%}{{x}}{% endfor %}
    <div class="box-body">
    {% for msg in get_flashed_messages(category_filter=['ok']) %}   # 过滤显示flashed信息
            <h4><i class="icon fa fa-warning"></i> 操作成功!</h4>
                    {{msg}}
            </div>
    {% endfor %}
    {% for msg in get_flashed_messages(category_filter=['err']) %}
            <h4><i class="icon fa fa-warning"></i> 操作失败!</h4>
                    {{msg}}
            </div>
    {% endfor %}
    <div class="form-group">
            <label for="input_title">{{form.title.label}}</label>
            {{form.title}}
            {% for err in form.title.errors %}   # 显示validators的错误信息
                  <div class="col-md-12">
                        <font style="color: red;">{{err}}</font>
                  </div>
             {% endfor %}
    </div>
    

    后台

    1. 编写wtforms.validators的ValidationError自定义验证器时,方法名后缀一定要和参数名相同,否则不会触发该验证



    FlaskForm

    from flask_wtf import FlaskForm

    class RoleForm(FlaskForm):   # 继承FlaskForm类
        name = StringField(   # 表单类型 StringField, PasswordField, SubmitField, FileField, TextAreaField, SelectField, SelectMultipleField
            label="角色名称",   # {{form.label}}
            validators=[   # 验证器
                DataRequired("请输入角色名称")
            ],
            description="角色名称",
            render_kw={   # 元素属性
                "class": "form-control",
                "id": "input_name",
                "placeholder": "请输入角色名称!"
            }
        )
    star = SelectField(
            label="星级",
            validators=[
                DataRequired("请选择星级!")
            ],
            description="星级",
            coerce=int,
            choices=[(1, "1星"), (2, "2星"), (3, "3星"), (4, "4星"), (5, "5星")],
            render_kw={
                "class": "form-control"
            }
        )
        auths = SelectMultipleField(
            label="权限列表",
            validators=[
                DataRequired("请选择权限")
            ],
            coerce=int,
            choices=[(v.id, v.name) for v in auth_list],
            description="权限列表",
            render_kw={
                "class": "form-control"
            }
        )
        submit = SubmitField(
            "编辑",
            render_kw={
                "class": "btn btn-primary"
            }
        )
        def validate_account(self, field):   # 自定义验证器,第一个参数必须是self,方法名称必须是validate_变量名,否则无法匹配生效
            account = field.data
            admin = Admin.query.filter_by(name=account).count()
            if admin == 0:
                raise ValidationError("账号不存在!")
    
        def __repr__(self):   #  打印方法
            return "<Admin %r>" % self.name
    
    1. 登录验证装饰器
    def admin_login_req(f):
        @wraps(f)
        def decorated_function(*args, **kwargs):
            if 'admin' not in session:
                return redirect(url_for('admin.login', next=request.url))
            return f(*args, **kwargs)
    
        return decorated_function
    

    使用时将@admin_login_req注解写在方法上

    1. 权限控制装饰器
    def admin_auth(f):
        @wraps(f)
        def decorated_function(*args, **kwargs):
            admin = Admin.query.join(
                Role
            ).filter(
                Admin.role_id == Role.id,
                Admin.id == session['admin_id']
            ).first()
            auths = admin.role.auths
            auths = list(map(lambda v: int(v), auths.split(',')))
            auth_list = Auth.query.all()
            urls = [v.url for v in auth_list for val in auths if val == v.id]
            rule = request.url_rule
            print(urls)
            print(rule)
            if str(rule) not in urls:
                abort(404)
            return f(*args, **kwargs)
        return decorated_function
    

    使用时将@admin_auth注解写在方法上

    1. 上下文应用处理器 封装全局变量,展现到模板中
    @admin.context_processor
    def tpl_extra():
        data = dict(
            online_time=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        )
        return data
    

    使用时在模板中用{{online_time}}调用

    1. 获取当前日期并格式化,及生成uuid
    1. werkzeug库
      from werkzeug.security import generate_password_hash
      from werkzeug.security import check_password_hash
      def check_pwd(self, pwd): # 检查密码
      from werkzeug.security import check_password_hash
      return check_password_hash(self.pwd, pwd)

    2. Gists

    Gist 作用
    request.url_rule 获取请求url
    request.remote_addr 获取请求地址
    Auth.query.all() 查询数据
    Admin.query.filter_by(name=data['account']).first() 查询数据
    db.session.add(admin_log) 插入数据
    db.session.delete(movie) 删除数据
    db.session.commit() 提交数据
    session.pop('admin', None) 删除session
    Tag.query.filter_by(name=data['name']).count() 统计
    page_data = Tag.query.order_by(Tag.add_time.desc()).paginate(page=page, per_page=10) 排序 分页
    Tag.query.filter_by(id=id).first_or_404() 找不到则返回404
    @admin.route('/tag/del/<int:id>/', methods=['GET']) 路径参数
    flash('添加电影成功', 'ok') {% for msg in get_flashed_messages(category_filter=['ok']) %}
    page_data = Movie.query.join(Tag).filter(Movie.tag_id == Tag.id).order_by(Movie.add_time.desc()).paginate(page=page, per_page=10) 多表关联,排序分页
    Movie.query.filter_by(title=data['title']).count() 筛选查询
    if form.validate_on_submit() 用自定义的验证器验证表单
    json.dumps({"t": str(datetime.datetime.now()), 'action': 'getJson'}) 格式化为json
    request.args.get("next") 获取转发链接
    page_data = MovieCol.query.join(Movie).join(User).filter(Movie.id == MovieCol.movie_id,User.id == 1).filter_by(Movie.title == '战狼').order_by(Movie.add_time.desc()).paginate(page=1,per_page=10) N个表关联

    相关文章

      网友评论

        本文标题:慕课网 python微电影项目 小知识点整理

        本文链接:https://www.haomeiwen.com/subject/ohnjhftx.html