Flask project 1 actual combat: 4, personal center (to be improved)

Insert picture description here

(According to the content of teacher's live broadcast)

One, login decorator

  • There are many pages that need to determine whether the user is logged in before entering, and even user information will be used
  • The flask framework has a hook function and before_request, which will be called before each request
  • Not all pages of this project need to be logged in, some pages can be browsed without registering and logging in
  • You can also use decorators,

1. Define the decorator function

  • This function is not a business logic function, and many methods are shared. It is recommended to define it in commons.py in the utils package
  • Define the closure, @functools()
  • Realize login check in inner function
    • Remove user_id from session
    • Determine whether user_id is empty
      • Is empty, returns an error message: the user is not logged in
      • Exist, means logged in, use g object to store user_id, return the decorated function
# lghome/commons.py

# view_func 被装饰的函数
def login_requre(view_func):

    @functools.wrapper(view_func)   # 保持原函数的属性
    def wrapper(*args,**kwargs):
        # 判断用户的登录状态
        user_id = session.get('user_id')
        if user_id is not None:
            # 已登录
            g.user_id=user_id
            return view_func(*args, **kwargs)
        else:
            # 未登录
            return jsonify(errno=RET.SESSIONERR, errmsg='用户未登陆')
    return wrapper

2. User uploads avatar (modify user information)

1. Package of Qiniu Cloud image upload function

def storage(file_data):
    # 构建鉴权对象
    q = Auth(access_key, secret_key)
    # 要上传的空间
    bucket_name = 'home-image-flask'
    # 上传后保存的文件名
    # key = 'my-python-logo.png'
    # 生成上传 Token,可以指定过期时间等
    token = q.upload_token(bucket_name, None, 3600)

    ret, info = put_data(token, None, file_data)
    if info.status_code == 200:
        return ret.get('key')
    else:
        raise Exception('上传图片失败')
    # print(ret)
    # print("-"*50)
    # print(info)

2. User upload avatar interface design

2.1 Request method

Options Program
Request method POST
Request address /users/avatar

2.2 Request parameters: form parameters

parameter name Types of Must pass Description
avatar file Yes profile picture

2.3 Response results

Response result Response content
Save failed Respond to error prompts
Saved successfully Return to the current page

3. User upload avatar interface definition

  • First apply the login decorator
  • If you are not logged in, return directly to sessionerr and jump to the login interface
  • After entering the function, first get the user_id in the g object
  • Get parameter image_file
  • If the parameter is None (that is, the picture is not transmitted), an error is returned
  • Read file
  • save Picture
    • There are several ways to save pictures
      • Database server: high requirements for server nature, resources, and data software
      • Server directory: to prevent duplicate file names, resources, performance requirements, etc.,
      • Third-party platform: such as Qiniu cloud platform (recommended by personal system)
      • Build your own file storage server: such as FastDFS fast distributed file storage system, mainly used for e-commerce companies, mainly pictures; HDFS Hadoop distributed file system (any file will do)
  • Save image path
    • Save the picture address in the database, just save the file name, the first half of the domain name of the picture address is saved in the constant file
lghome/api_1_0/profile.py 

@api.route("/users/avatar",methods=["POST"])
@login_required
def set_user_avatar():    """
    设置用户的头像
    :param: 图片
    :return: avatar_url 头像的地址
    """
    user_id = g.user_id

    # 获取图片
    image_file = request.files.get('avatar')
    # print(image_file)
    # print(type(image_file))

    if image_file is None:
        return jsonify(errno=RET.PARAMERR, errmsg='未上传图片')

    # 图片的二进制数据
    image_data = image_file.read()

    # 上传到七牛云
    try:
        file_name = storage(image_data)
    except Exception as e:
        logging.error(e)
        return jsonify(errno=RET.THIRDERR, errmsg='上传图片失败')

    # 保存到数据库中
    # file_name FoRZHZTBj2xRSDa_Se0Rvx26qm0C
    # URL  http://qkgi1wsiz.hd-bkt.clouddn.com/FoRZHZTBj2xRSDa_Se0Rvx26qm0C
    # 保存 file_name
    # http://qkgi1wsiz.hd-bkt.clouddn.com/
    try:
        User.query.filter_by(id=user_id).update({
    
    "avatar_url": file_name})
        db.session.commit()
    except Exception as e:
        # 出现异常回滚
        db.session.rollback()
        logging.error(e)
        return jsonify(errno=RET.DBERR, errmsg='保存图片信息失败')

    avatar_url = constants.QINIU_URL_DOMAIN + file_name
    return jsonify(errno=RET.OK, errmsg='保存成功', data={
    
    "avatar_url": avatar_url})

3、

Three, modify the user name

1. Modify the user name interface design

1.1 Request method

Options Program
Request method PUT
Request address /users/name

1.2 Request parameters: form parameters

parameter name Types of Must pass Description
name string Yes username

1.3 Response results

Response result Response content
Save failed Respond to error prompts
Saved successfully

2. Modify the user name interface definition

  • First apply the login decorator
  • If you are not logged in, return directly to sessionerr and jump to the login interface
  • After entering the function, first get the user_id in the g object
  • Get parameter name
  • If the parameter is None, return an error message
  • Update user name
    • If the user repeats the data exception, the name is uniqure
  • Return result
@api.route("users/name",methods=["PUT"])
@login_required
def change_user_name():
    """
    修改用户名
    :return: 修改用户名成功或者失败
    """
    user_id = g.user_id

    # 获取用户提交的用户名
    request_data = request.get_json()

    if request_data is None:
        return jsonify(errno=RET.PARAMERR, errmsg='参数不完整')

    user_name=request_data.get("name")
    try:
        User.query.filter_by(id=user_id).update({
    
    "name": user_name})
        db.session.commit()
    except IntegrityError as e :
        logging.error(e)
        db.session.rollback()
        return jsonify(errno=RET.DBERR, errmsg='用户名已经存在')
    except Exception as e:
        logging.error(e)
        db.session.rollback()
        return jsonify(errno=RET.DBERR, errmsg='设置用户名错误')

    # 更新session数据
    session["name"] = user_name

    return jsonify(errno=RET.OK, errmsg='OK')

Fourth, obtain personal information (refresh the user information page)

1. Modify the user name interface design

1.1 Request method

Options Program
Request method GET
Request address /user

1.2 Request parameters: none

1.3 Response results

first name Types of Do you have to Description
errno String no error code
errmsg String no Error content
data dictionary no Personal information dictionary

2. Modify the user name interface definition

  • First apply the login decorator
  • If you are not logged in, return directly to sessionerr and jump to the login interface
  • After entering the function, first get the user_id in the g object
  • Obtain user information according to user_id
    • If the user information does not exist or the data is reported incorrectly, return the error information
      according to the personal information dictionary (define the dictionary method to return personal information in the User class)
@api.route("/user",methods=["GET"])
@login_required
def get_user_profile():
    """
    获取个人信息
    :return: 用户名,用户头像URL
    """
    user_id = g.user_id
    print(user_id)

    try:
        user=User.query.get(user_id)
        print(user)
    except Exception as e:
        logging.error(e)
        return jsonify(errno=RET.DBERR,errmsg="用户信息查询失败")

    if user is None:
        print("None")
        return jsonify(errno=RET.NODATA, errmsg="用户信息查询失败")
        
    print("user.to_dict()=",user.to_dict())
    return jsonify(errno=RET.OK,errmsg="",data=user.to_dict())

Six, real-name authentication

  • It needs to be connected to the public security system and can be developed according to the interface document. Individuals cannot complete data verification.
  • This project does not judge the real-name authentication information for the time being, and save it directly to the database

1. Real-name authentication interface design

1.1 Request method

Options Program
Request method POST
Request address /users/auth

1.2 Request parameters: form parameters

parameter name Types of Must pass Description
id_card string Yes identity number
real_name string Yes actual name

1.3 Response results

first name Types of Do you have to Description
errno String no error code
errmsg String no Error content
data dictionary no {“id_card”:“xxx”,“real_name”:“XXXXX”}

2. Real-name authentication interface definition

  • First apply the login decorator
  • If you are not logged in, return directly to sessionerr and jump to the login interface
  • After entering the function, first get the user_id in the g object
  • Get parameters and judge validity
    • Whether both parameters exist
    • Whether the two energy numbers meet the specification
  • Call the public security interface (this function is temporarily unavailable), the default verification is successful
  • Update the user's real name and ID according to user_id
  • Return result
@api.route("/users/auth",methods=["POST"])
@login_required
def set_user_auth():
    """
    保存实名认证信息
    :return:
    """
    user_id = g.user_id

    request_dict = request.get_json()
    real_name=request_dict.get("real_name")
    id_card=request_dict.get("id_card")

    if not all([real_name,id_card]):
        return jsonify(errno=RET.DATAERR,errmsg="参数不完整")

    # 标验身份证格式
    # 校验用户名
    # 与公安系统对接,验证身份证和姓名正确性

    try:
        User.query.filter_by(id=user_id).update({
    
    "real_name":real_name,"id_card":id_card})
        db.session.commit()
    except Exception as e:
        logging(e)
        db.session.rollback()
        return jsonify(errno=RET.DBERR,errmsg="保存数据失败")

    return jsonify(errno=RET.OK,errmsg="ok",data={
    
    "real_name":real_name,"id_card":id_card})

3. Optimize the definition of real-name authentication interface

  • After the user’s real-name authentication, the real-name authentication should not be performed again and cannot be modified
  • After entering the function, it is directly judged whether the user has registered with the real name, if it has been registered, it will report an error and return
    • Get user information through user_id
    • Through all[user.real_name,user_id_card], it is judged that the real name has been registered
    try:
        user=User.query.get(user_id)
    except Exception as e:
        logging.error(e)
        return jsonify(errno=RET.DBERR,errmsg="用户信息查询失败")
    if all([user.real_name,user.id_card]):
        return jsonify(errno=RET.DATAEXIST,errmsg="用户已实名认证过,不能再修改")

Seven, obtain real-name authentication information

  • It needs to be connected to the public security system and can be developed according to the interface document. Individuals cannot complete data verification.
  • This project does not judge the real-name authentication information for the time being, and save it directly to the database

1. Interface design for obtaining real-name authentication information

1.1 Request method

Options Program
Request method POST
Request address /users/auth

1.2 Request parameters: none

1.3 Response results

first name Types of Do you have to Description
errno String no error code
errmsg String no Error content
data dictionary no {“id_card”:“xxx”,“real_name”:“XXXXX”}

2. Obtain the real-name authentication interface definition

  • First apply the login decorator
  • If you are not logged in, return directly to sessionerr and jump to the login interface
  • After entering the function, first get the user_id in the g object
  • Update the user's real name and ID according to user_id
  • Return result
@api.route("/users/auth",methods=["GET"])
@login_required
def get_user_auth():
    """
    获取个人信息
    :return: 用户名,用户头像URL
    """
    user_id = g.user_id

    try:
        user=User.query.get(user_id)
        print(user)
    except Exception as e:
        logging.error(e)
        return jsonify(errno=RET.DBERR,errmsg="用户信息查询失败")

    if user is None:
        print("None")
        return jsonify(errno=RET.DBERR, errmsg="用户信息查询失败")

    # print("user.auth_to_dict()=",user.auth_to_dict())
    return jsonify(errno=RET.OK,errmsg="ok",data=user.auth_to_dict())

Guess you like

Origin blog.csdn.net/laoluobo76/article/details/110632101