Flask问题汇总

模型类

from flask_sqlalchemy import SQLAlchemy
from datetime import datetime

db = SQLAlchemy()


class UserModel(db.Model):
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    name = db.Column(db.String(32), comment="用户名")
    password = db.Column(db.String(16), comment="密码,加密存储")
    order_id = db.relationship("OrderModel", backref="user")


class TonyModel(db.Model):
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    name = db.Column(db.String(32), comment="托尼")
    price = db.Column(db.Integer, comment="价格")
    service_id = db.Column(db.Integer, default=0, comment="服务对象id")
    order_id = db.relationship("OrderModel", backref="tony")


class OrderModel(db.Model):
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    start_time = db.Column(db.DateTime, comment="开始服务时间", default=datetime.now)
    end_time = db.Column(db.DateTime, comment="结束服务时间")
    price = db.Column(db.DECIMAL(10, 2), comment="价格")
    tony_id = db.Column(db.Integer, db.ForeignKey("tony_model.id"), comment="所属托尼")
    user_id = db.Column(db.Integer, db.ForeignKey("user_model.id"), comment="所属用户")

问题一:用户选择tony,tony只能被当前用户选择,不能被其他用户选择

              添加历史记录,计算总价格

1.在tony表中添加一个service_id字段

service_id = db.Column(db.Integer, default=0, comment="服务对象id")

2.如果用户选择了当前tony,就让service_id=用户id,来让其他用户选择不了,并添加历史记录

class TonyView(Resource): 
    @check_login
    def put(self):
        user_id = g.user_id
        req = reqparse.RequestParser()
        req.add_argument("tony_id")
        args = req.parse_args()
        tony_id = args["tony_id"]

        t = TonyModel.query.get(tony_id)
        if not t:
            return jsonify({
                "code": 400,
                "msg": "tony不存在"
            })

        if t.service_id != 0:
            return jsonify({
                "code": 400,
                "msg": "托尼正在忙"
            })

        t.service_id = user_id
        db.session.commit()

        # 生成一个订单 添加美发历史记录
        o = OrderModel(tony_id=tony_id, user_id=user_id)
        db.session.add(o)
        db.session.commit()

        return jsonify({
            "code": 200,
            "msg": "tony选择成功"
        })

3.设定字段状态来让页面显示tony状态

class TonyView(Resource):
    @check_login
    def get(self):
        user_id = g.user_id
        tony_list = TonyModel.query.all()

        status = ""
        temp = []
        for i in tony_list:
            if i.service_id == user_id:
                status = "结束"
            elif i.service_id == 0:
                status = "空闲"
            else:
                status = "正忙"
            temp_dict = {
                "id": i.id,
                "name": i.name,
                "price": i.price,
                "server": i.service_id,
                "status": status
            }
            temp.append(temp_dict)
        return jsonify({
            "code": 200,
            "msg": "展示成功",
            "data": temp
        })

4.释放tony,并计算服务时长,总价格

    @check_login
    def delete(self):
        user_id = g.user_id
        req = reqparse.RequestParser()
        req.add_argument("tony_id")
        args = req.parse_args()
        tony_id = args["tony_id"]

        order = OrderModel.query.filter(OrderModel.tony_id == tony_id, OrderModel.user_id == user_id,
                                        OrderModel.end_time == None).first()

        if not order:
            return jsonify({
                "code": 400,
                "msg": "没有正在进行的服务"
            })

        # 开始时间转换格式
        start_time = int(time.mktime(order.start_time.timetuple()))
        print("start_time>>>>>>>", start_time)

        # 查看服务多长时间
        # time.time()现在时间 时间戳
        all_time = int(time.time()) - start_time

        price = order.tony.price

        order_price = float(price) / 3600 * all_time  # 订单价格
        print("order_price>>>>>>", order_price)

        # 折扣
        zhekou = 0
        history_order = OrderModel.query.filter(OrderModel.user_id == user_id,
                                                OrderModel.end_time != None).all()
        if len(history_order) >= 3:
            zhekou = 0.85
            order_price = float(price) / 3600 * all_time * zhekou
            print("order_price333>>>>>>>", order_price)

        order.end_time = datetime.now()
        order.price = order_price

        # 还要修改tony服务者
        order.tony.service_id = 0
        db.session.commit()

        return jsonify({
            "code": 200,
            "msg": "结束服务"
        })

问题二:密码加密

def jiami(password):
    """md5加密"""
    import hashlib  # 内置的
    # 害怕被找出规律,所以要加上密钥
    password += current_app.config.get("SECRET_KEY")
    md5 = hashlib.md5()  # 实例化md5对象
    md5.update(password.encode("utf-8"))  # 传入要加密的字符串 因为参数要求必须传入bytes类型 所以需要把字符串编码为bytes类型
    sign = md5.hexdigest()  # 获取到加密结果
    print(sign)


if __name__ == '__main__':
    from app import app

    with app.app_context():
        jiami("11111")

问题三:退出登录 token禁用

后端

# 校验登录 解码token
def login(func):
    def inner(*args, **kwargs):
        req = reqparse.RequestParser()
        req.add_argument("token", location="headers")  # 必须指定参数获取位置
        args = req.parse_args()
        token = args["token"]
        if not token:
            return jsonify({
                "code": 400,
                "msg": "token不存在"
            })
        # 先判断一下token是否已经被禁用掉了
        res = RedisTool().res
        is_exists = res.exists("token_%s" % token)  # 判断某一个键是否存在 bool值
        # 如果失效token存在,说明token已禁用
        if is_exists:
            # 代表被禁用
            return jsonify({
                "code": 403,
                "msg": "用户未登录"
            })

        key = current_app.config.get("SECRET_KEY")

        try:
            payload = jwt.decode(token, key, algorithms="HS256")
            print("解码出的用户信息", payload)
        except Exception as e:
            print("解码失败", e)
            print("捕获异常的类型", type(e)) 
            # <class 'jwt.exceptions.ExpiredSignatureError'>
            return jsonify({
                "code": 403,
                "msg": "用户未登录"
            })

        g.user_id = payload["user_id"]  # user_id从token中的payload部分解析出来

        return func(*args, **kwargs)

    return inner


class Login(Resource):

    @login
    def delete(self):
        req = reqparse.RequestParser()
        req.add_argument("token",location="headers")
        args = req.parse_args()
        token = args["token"]

        """
        前端点击退出登录,把退出登录的token存到redis,此时说明我们往redis里存的是 已经退出登录失效                
        的token
        然后在强制登陆的装饰器里校验 如果redis里有退出登录后写入的失效token,那就说明token已经禁用
        """
        # 存到redis的目的 让某一个token失效
        # token本身是有有效期的
        res = RedisTool().res
        res.set("token_%s" % token, "1", ex=7200)

        return jsonify({
            "code": 200,
            "msg": "退出登录成功"
        })

前端

 <template>
  <div class="container">
    <el-button type="primary" @click="login_out">退出登录</el-button>
  </div>
</template>
<script>
export default {
   methods:{
   // 退出登录 清空token
    login_out() {
      this.$axios
        .delete("/user/login",{
          headers: {
            token: localStorage.getItem("token"),
          },
        })
        .then((resp) => {
          console.log("退出登录的响应", resp);
          //清空本地存储token
          localStorage.removeItem("token");
        })
        .catch((err) => {
          console.log(err);
        });

      //跳转到登录页面
      this.$router.push("/login");
    },
  }
}
</script>

图片验证码

后端

from captcha.image import ImageCaptcha
from model.model import UserModel, db
import redis
from flask import Blueprint, jsonify, current_app, g, send_file, request
from flask_restful import reqparse, Resource, Api
import random

user_bp = Blueprint("user_bp", __name__, url_prefix="/user")

api = Api(user_bp)

# 生成图形验证码
class ImageCode(Resource):
    def get(self, uuid):
        if not uuid:
            return jsonify({
                "code": 400,
                "msg": "数据不能为空"
            })
        code = str(random.randint(1000, 9999))

        res = redis.Redis(host="127.0.0.1", port=6379, password="123456")
        res.set("image_%s" % uuid, code, ex=5 * 60)

        img = ImageCaptcha()
        img_code = img.generate(code, format="png")

        return send_file(img_code, "png")

api.add_resource(ImageCode, "/img/<uuid>")

前端

<template>
  <div>
    图片验证码:<input type="text" v-model="code" />
    <img :src="'http://127.0.0.1:5000/user/img/' + uuid" @click="checkImage" />
  </div>
</template>

<script>
import { v4 as uuid4 } from "uuid";
export default {
  name: "Login",
  data() {
    return {
      code: "",
      uuid: ""
    };
  },
  mounted() {
    this.checkImage();
  },
  methods: {
    checkImage() {
      this.uuid = uuid4();
    }
  }
};
</script>

<style scoped></style>

问题: 自动生成大小写字母数字混合的6位用户名,且不可重复。

# 生成6位随机大小写数字+大小写字母
# string.ascii_letters 大小写字母
# random.sample(参数1,n) 随机生成n位
username = random.sample(string.digits + string.ascii_letters, 6)
# "".json(参数) 以空字符串的方式把列表里的数据连接起来
username = str("".join(username))
# 死循环
while True:
    u = UserModel.query.filter(UserModel.username == username).first()
    # 如果用户名存在
    if u:
        # 重新生成
        username = random.sample(string.digits + string.ascii_letters, 6)
        username = str("".join(username))
    # 不存在跳出循环
    else:
        break

问题:用户注册时随机选择一个头像

# 随机五个头像
img = ["01.png", "02.png", "03.jpg", "04.png"]
# random.shuffle(img)把列表里的数据随机打乱
random.shuffle(img)
# 存入数据库,取随机后第一个头像
img = "static/" + img[0]

问题:统计一个小时内注册的用户

u = UserModel.query.all()
temp = []
count = 0
for i in u:
    # 开始转换时间格式 注册时间
    create_time = int(time.mktime(i.create_time.timetuple()))

    # 现在时间
    all_time = int(time.time()) - create_time
    # 3600是一个小时 60分*60秒
    all_time = all_time / 3600
    print(all_time)

    # 统计一个小时内注册用户
    if all_time <= 1:
       count += 1

flask上传文件

后端

class UploadView(BaseView):
    def post(self):
        img = request.files.get("img")
        filename = datetime.strftime(datetime.now(), "%Y%m%d%H%M%S") + str(random.randint(10000, 99999))
        filename += "." + img.filename.split(".")[-1]
        img.save("./static/" + filename)

        # 上传到七牛云
        from qiniu import Auth, put_file, etag
        # 需要填写你的 Access Key 和 Secret Key
        access_key = ''
        secret_key = ''
        # 构建鉴权对象
        q = Auth(access_key, secret_key)
        # 要上传的空间
        bucket_name = 'sssxiaoxi'
        # 上传后保存的文件名
        key = 'static/' + filename
        # 生成上传 Token,可以指定过期时间等
        token = q.upload_token(bucket_name, key, 3600)
        # 要上传文件的本地路径
        localfile = './static/' + filename
        ret, info = put_file(token, key, localfile, version='v2')
        print(info)
        if ret['key'] == key:
            return self.success(data={
                "filepath": "static/" + filename
            })
        else:
            return self.error(msg="上传图片失败")


class UploadMp3(BaseView):
    def get(self):
        from qiniu import Auth
        access_key = current_app.config.get("QINIU_AK")
        secret_key = current_app.config.get("QINIU_SK")
        auth = Auth(access_key, secret_key)
        backet_name = "sssxiaoxi"
        token = auth.upload_token(backet_name, expires=3600)

        return self.success({
            "token": token
        })

前端

<el-upload
   action="http://127.0.0.1:5000/admin/upload/img"
   name="img"
   :on-success="upload"
   :show-file-list="false"
>
<div><img class="img" :src="user_info.host + user_info.avatar" /></div>
</el-upload>


upload(res) {
    console.log(res);
    if (res.code == 20000) {
      this.user_info.avatar = res.data.filepath;
    } else {
      this.$message.error(res.data.msg);
    }
  },
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值