caogao

·marshmallow.py

from marshmallow import Schema,fields,validate,validates,ValidationError
from message import ErrorMessage as Message
from .models import User,db
class MobileSchema(Schema):
    mobile = fields.String(required=True,validate=validate.Regexp("^1[3-9]\d{9}$",error=Message.mobile_format_error))

    @validates("mobile")
    def validates_mobile(self,data):
        user = User.query.filter(User.mobile==data).first()
        if user is not None:
            raise ValidationError(message=Message.mobile_is_use)
        return data

from marshmallow_sqlalchemy import SQLAlchemyAutoSchema,auto_field
from marshmallow import post_load,pre_load,validates_schema
from application import redis
class UserSchema(SQLAlchemyAutoSchema):
    mobile = auto_field(required=True, load_only=True)
    password = fields.String(required=True, load_only=True)
    password2 = fields.String(required=True, load_only=True)
    sms_code = fields.String(required=True, load_only=True)

    class Meta:
        model = User
        include_fk = True # 启用外键关系
        include_relationships = True # 模型关系外部属性
        fields = ["id", "name","mobile","password","password2","sms_code"] # 如果要全换全部字段,就不要声明fields或exclude字段即可
        sql_session = db.session

    @post_load()
    def save_object(self, data, **kwargs):
        data.pop("password2")
        data.pop("sms_code")
        data["name"] = data["mobile"]
        instance = User(**data)
        db.session.add( instance )
        db.session.commit()
        return instance

    @validates_schema
    def validate(self,data, **kwargs):
        # 校验密码和确认密码
        if data["password"] != data["password2"]:
            raise ValidationError(message=Message.password_not_match,field_name="password")

        #todo 校验短信验证码
        #1. 从redis中提取验证码
        redis_sms_code = redis.get("sms_%s" % data["mobile"])
        if redis_sms_code is None:
            raise ValidationError(message=Message.sms_code_expired,field_name="sms_code")
        redis_sms_code = redis_sms_code.decode()
        #2. 从客户端提交的数据data中提取验证码
        sms_code = data["sms_code"]
        #3. 字符串比较,如果失败,则抛出异常,否则,直接删除验证码
        if sms_code != redis_sms_code:
            raise ValidationError(message=Message.sms_code_error, field_name="sms_code")

        redis.delete("sms_%s" % data["mobile"])

        return data

from marshmallow import post_dump
class UserInfoSchema(SQLAlchemyAutoSchema):
    id = auto_field()
    mobile = auto_field()
    nickname = auto_field()
    avatar = auto_field()

    class Meta:
        model = User
        include_fk = True
        include_relationships = True
        fields = ["id","mobile","nickname","avatar"]
        sql_session = db.session

    @post_dump()
    def mobile_format(self, data, **kwargs):
        data["mobile"] = data["mobile"][:3]+"****"+data["mobile"][-4:]
        return data

from sqlalchemy import or_,and_
from .models import UserRelation
from application import mongo
from datetime import datetime
class UserSearchInfoSchema(SQLAlchemyAutoSchema):
    """用户搜索信息返回"""
    id = auto_field()
    nickname = auto_field()
    avatar = auto_field()
    relation_status = fields.String(dump_only=True)

    @post_dump()
    def relation_status_post(self, data, **kwargs):
        relaionship = UserRelation.query.filter(
            or_(
                and_(UserRelation.send_user==self.context["user_id"], UserRelation.receive_user==data["id"]),
                and_(UserRelation.receive_user==self.context["user_id"], UserRelation.send_user==data["id"]),
            )
        ).first()
        if relaionship is not None and relaionship.relation_status==1:
            """判断当前双方是否是好友"""
            data["relation_status"] = UserRelation.relation_status_chioce[relaionship.relation_status-1]
        else:
            # 判断当前用户是否曾经添加过对方
            query = {
                "$or":[{
                    "$and":[
                        {
                            "send_user_id": self.context["user_id"],
                            "receive_user_id": data["id"],
                            "time": {"$gte":datetime.now().timestamp() - 60 * 60 * 24 * 7}
                        }
                    ],
                },{
                    "$and": [
                        {
                            "send_user_id": data["id"],
                            "receive_user_id": self.context["user_id"],
                            "time": {"$gte": datetime.now().timestamp() - 60 * 60 * 24 * 7}
                        }
                    ],
                }]
            }
            document_list = mongo.db.user_relation_history.find(query,{"_id":0}).sort("time",-1)
            document = [document for document in document_list]
            print(document)
            if len(document) > 0:
                document = document[0]
                if document.get("send_user_id") == self.context["user_id"]:
                    if document.get("status") == 0:
                        data["relation_status"]  = (0, "已添加")
                    elif document.get("status") == 1:
                        data["relation_status"]  = (1, "已通过")
                    elif document.get("status") == 2:
                        data["relation_status"]  = (2, "已拒绝")
                    else:
                        data["relation_status"]  = (3, "已取消")
                else:
                    if document.get("status") == 0:
                        data["relation_status"]  = (0, "等待通过")
                    elif document.get("status") == 1:
                        data["relation_status"]  = (1, "已通过")
                    elif document.get("status") == 2:
                        data["relation_status"]  = (2, "已拒绝")
                    else:
                        data["relation_status"]  = (3, "已取消")
            else:
                data["relation_status"] = (0,"添加")

        return data

    class Meta:
        model = User
        include_fk = True
        include_relationships = True
        fields = ["id","nickname","avatar","relation_status"]
        sql_session = db.session

·viewspy

from application import jsonrpc,db
from .marshmallow import MobileSchema,UserSchema
from marshmallow import ValidationError
from message import ErrorMessage as Message
from status import APIStatus as status
@jsonrpc.method("User.mobile")
def mobile(mobile):
    """验证手机号码是否已经注册"""
    ms = MobileSchema()
    try:
        ms.load({"mobile":mobile})
        ret = {"errno":status.CODE_OK, "errmsg":Message.ok}
    except ValidationError as e:
        ret = {"errno":status.CODE_VALIDATE_ERROR, "errmsg": e.messages["mobile"][0]}
    return ret

@jsonrpc.method("User.register")
def register(mobile,password,password2, sms_code):
    """用户信息注册"""

    try:
        ms = MobileSchema()
        ms.load({"mobile": mobile})

        us = UserSchema()
        user = us.load({
            "mobile":mobile,
            "password":password,
            "password2":password2,
            "sms_code": sms_code
        })
        data = {"errno": status.CODE_OK,"errmsg":us.dump(user)}
    except ValidationError as e:
        data = {"errno": status.CODE_VALIDATE_ERROR,"errmsg":e.messages}
    return data

from flask_jwt_extended import create_access_token,create_refresh_token,jwt_required,get_jwt_identity,jwt_refresh_token_required
from flask import jsonify,json
from sqlalchemy import or_
from .models import User
from message import ErrorMessage as message
from status import APIStatus as status
from flask import current_app,request
from urllib.parse import urlencode
from urllib.request import urlopen
@jsonrpc.method("User.login")
def login(ticket,randstr,account,password):
    """根据用户登录信息生成token"""
    # 校验防水墙验证码
    params = {
        "aid": current_app.config.get("CAPTCHA_APP_ID"),
        "AppSecretKey": current_app.config.get("CAPTCHA_APP_SECRET_KEY"),
        "Ticket": ticket,
        "Randstr": randstr,
        "UserIP": request.remote_addr
    }
    # 把字典数据转换成地址栏的查询字符串格式
    # aid=xxx&AppSecretKey=xxx&xxxxx
    params = urlencode(params)
    url = current_app.config.get("CAPTCHA_GATEWAY")
    # 发送http的get请求
    f = urlopen("%s?%s" % (url, params))
    # https://ssl.captcha.qq.com/ticket/verify?aid=xxx&AppSecretKey=xxx&xxxxx

    content = f.read()
    res = json.loads(content)
    print(res)

    if int(res.get("response")) != 1:
        # 验证失败
        return {"errno": status.CODE_CAPTCHA_ERROR, "errmsg": message.captcaht_no_match}

    # 1. 根据账户信息和密码获取用户
    if len(account) < 1:
        return {"errno":status.CODE_NO_ACCOUNT,"errmsg":message.account_no_data}
    user = User.query.filter(or_(
        User.mobile==account,
        User.email==account,
        User.name==account
    )).first()

    if user is None:
        return {"errno": status.CODE_NO_USER,"errmsg":message.user_not_exists}

    # 验证密码
    if not user.check_password(password):
        return {"errno": status.CODE_PASSWORD_ERROR, "errmsg":message.password_error}

    # 2. 生成jwt token
    access_token = create_access_token(identity=user.id)
    refresh_token = create_refresh_token(identity=user.id)

    return {
        "errno": status.CODE_OK,
        "errmsg": message.ok,
        "id": user.id,
        "nickname": user.nickname if user.nickname else account,
        "access_token": access_token,
        "refresh_token":refresh_token
    }

from .marshmallow import UserInfoSchema
@jsonrpc.method("User.info")
@jwt_required # 验证jwt
def info():
    """获取用户信息"""
    current_user_id = get_jwt_identity() # get_jwt_identity 用于获取载荷中的数据
    user = User.query.get(current_user_id)
    if user is None:
        return {
            "errno": status.CODE_NO_USER,
            "errmsg": message.user_not_exists,
        }
    uis = UserInfoSchema()
    data = uis.dump(user)

    return {
        "errno": status.CODE_OK,
        "errmsg": message.ok,
        "is_set_transaction_password": bool(user.transaction_password),
        **data
    }

@jsonrpc.method("User.check")
@jwt_required # 验证jwt
def check():
    return {
        "errno": status.CODE_OK,
        "errmsg": message.ok,
    }

@jsonrpc.method("User.refresh")
@jwt_refresh_token_required # 验证refresh_token
def refresh():
    """重新获取新的认证令牌token"""
    current_user_id = get_jwt_identity()
    user = User.query.get(current_user_id)
    if user is None:
        return {
            "errno": status.CODE_NO_USER,
            "errmsg": message.user_not_exists,
        }

    # 重新生成token
    access_token = create_access_token(identity=current_user_id)
    return {
        "errno": status.CODE_OK,
        "errmsg": message.ok,
        "access_token": access_token
    }

import base64, uuid,os
from application import mongo
from datetime import datetime
@jsonrpc.method("User.avatar.update")
@jwt_required # 验证jwt
def update_avatar(avatar):
    """获取用户信息"""
    # 1. 接受客户端上传的头像信息
    ext = avatar[avatar.find("/")+1:avatar.find(";")]  # 资源格式
    b64_avatar = avatar[avatar.find(",")+1:]
    b64_image = base64.b64decode(b64_avatar)
    filename = uuid.uuid4()
    static_path = os.path.join( current_app.BASE_DIR,current_app.config["STATIC_DIR"] )
    with open("%s/%s.%s" % (static_path, filename,ext),"wb") as f:
        f.write(b64_image)

    current_user_id = get_jwt_identity()
    user = User.query.get(current_user_id)
    if user is None:
        return {
            "errno": status.CODE_NO_USER,
            "errmsg": message.user_not_exists,
        }
    user.avatar = "%s.%s" % (filename,ext)
    db.session.commit()
    # 添加修改记录!
    document = {
        "user_id": user.id,
        "user_name": user.name,
        "user_nikcname": user.nickname,
        "updated_time": datetime.now().timestamp(), # 修改时间
        "avatar": avatar, # 图片内容
        "type": "avatar",    # 本次操作的类型
    }
    mongo.db.user_info_history.insert_one(document)

    return {
        "errno": status.CODE_OK,
        "errmsg": message.avatar_save_success,
        "avatar": "%s.%s" % (filename,ext)
    }
import os
from flask import make_response,request
@jwt_required # 验证jwt
def avatar():
    """获取头像信息"""
    avatar = request.args.get("sign")
    ext  = avatar[avatar.find(".")+1:]
    filename = avatar[:avatar.find(".")]
    static_path = os.path.join(current_app.BASE_DIR, current_app.config["STATIC_DIR"])
    file = "%s/%s.%s" % (static_path,filename,ext)
    if not os.path.isfile(file):
        ext = "jpeg"
        file = "%s/%s.%s" % (static_path, "496b8ee8-b445-486d-b006-d957d42ce67f", ext) # 在配置文件中设置为默认头像即可
    with open(file, "rb") as f:
        content = f.read()
    response = make_response(content)
    response.headers["Content-Type"] = "image/%s" % ext
    return response


@jsonrpc.method("User.transaction.password")
@jwt_required # 验证jwt
def transaction_password(password1, password2,old_password=None):
    """
    交易密码的初始化和修改
    1. 刚注册的用户,没有交易密码,所以此处填写的是新密码
    2. 已经有了交易密码的用户,修改旧的交易密码
    """

    if password1 != password2:
        return {
            "errno": status.CODE_TRANSACTION_PASSWORD_ERROR,
            "errmsg": message.transaction_password_not_match
        }

    current_user_id = get_jwt_identity()
    user = User.query.get(current_user_id)
    if user is None:
        return {
            "errno": status.CODE_NO_USER,
            "errmsg": message.user_not_exists,
        }

    # 如果之前有存在交易密码,则需要验证旧密码
    if user.transaction_password:
        """修改"""
        # 验证旧密码
        ret = user.check_transaction_password(old_password)
        if ret == False:
            return {
                "errno": status.CODE_PASSWORD_ERROR,
                "errmsg": message.transaction_password_error
            }

    """设置交易密码"""
    user.transaction_password = password1
    db.session.commit()

    # 添加交易密码的修改记录,为了保证安全,仅仅记录旧密码!
    if old_password:
        document = {
            "user_id": user.id,
            "user_name": user.name,
            "user_nikcname": user.nickname,
            "updated_time": datetime.now().timestamp(),        # 修改时间
            "transaction_password": old_password, # 变更内容
            "type": "transaction_password",    # 本次操作的类型
        }
        mongo.db.user_info_history.insert_one(document)

    return {
        "errno": status.CODE_OK,
        "errmsg": message.ok
    }

from sqlalchemy import or_
from .models import UserRelation
from .marshmallow import UserSearchInfoSchema as usis
@jsonrpc.method("User.user.relation")
@jwt_required # 验证jwt
def user_relation(account):
    """搜索用户信息"""
    current_user_id = get_jwt_identity()
    user = User.query.get(current_user_id)
    if user is None:
        return {
            "errno": status.CODE_NO_USER,
            "errmsg": message.user_not_exists,
        }

    # 1. 识别搜索用户
    receive_user_list = User.query.filter( or_(
        User.mobile == account,
        User.name == account,
        User.nickname.contains(account),
        User.email==account
    ) ).all()

    if len(receive_user_list) < 1:
        return {
            "errno": status.CODE_NO_USER,
            "errmsg": message.receive_user_not_exists,
        }
    # context 可用于把视图中的数据传递给marshmallow转换器中使用
    marshmallow = usis(many=True,context={"user_id": user.id})
    user_list = marshmallow.dump(receive_user_list)
    return {
        "errno": status.CODE_OK,
        "errmsg": message.ok,
        "user_list": user_list
    }

@jsonrpc.method("User.friend.add")
@jwt_required # 验证jwt
def add_friend_apply(user_id):
    """申请添加好友"""
    current_user_id = get_jwt_identity()
    user = User.query.get(current_user_id)
    if user is None:
        return {
            "errno": status.CODE_NO_USER,
            "errmsg": message.user_not_exists,
        }

    receive_user = User.query.get(user_id)
    if receive_user is None:
        return {
            "errno": status.CODE_NO_USER,
            "errmsg": message.receive_user_not_exists,
        }

    # 查看是否被对方拉黑了

    # 添加一个申请记录
    document = {
        "send_user_id": user.id,
        "send_user_nickname": user.nickname,
        "send_user_avatar": user.avatar,
        "receive_user_id": receive_user.id,
        "receive_user_nickname": receive_user.nickname,
        "receive_user_avatar": receive_user.avatar,
        "time": datetime.now().timestamp(),  # 操作时间
        "status": 0,
    }
    mongo.db.user_relation_history.insert_one(document)
    return {
        "errno": status.CODE_OK,
        "errmsg": message.ok,
    }

from sqlalchemy import and_
@jsonrpc.method("User.friend.apply")
@jwt_required # 验证jwt
def add_friend_apply(user_id,agree,search_text):
    """处理好友申请"""
    current_user_id = get_jwt_identity()
    user = User.query.get(current_user_id)
    if user is None:
        return {
            "errno": status.CODE_NO_USER,
            "errmsg": message.user_not_exists,
        }

    receive_user = User.query.get(user_id)
    if receive_user is None:
        return {
            "errno": status.CODE_NO_USER,
            "errmsg": message.receive_user_not_exists,
        }

    relaionship = UserRelation.query.filter(
        or_(
            and_(UserRelation.send_user == user.id, UserRelation.receive_user == receive_user.id),
            and_(UserRelation.receive_user == user.id, UserRelation.send_user == receive_user.id),
        )
    ).first()

    if agree:
        if receive_user.mobile == search_text:
            chioce = 0
        elif receive_user.name == search_text:
            chioce = 1
        elif receive_user.email== search_text:
            chioce = 2
        elif receive_user.nickname == search_text:
            chioce = 3
        else:
            chioce = 4

        if relaionship is not None:
            relaionship.relation_status = 1
            relaionship.relation_type = chioce
            db.session.commit()
        else:
            relaionship = UserRelation(
                send_user=user.id,
                receive_user=receive_user.id,
                relation_status=1,
                relation_type=chioce,
            )
            db.session.add(relaionship)
            db.session.commit()

    # 调整mongoDB中用户关系的记录状态
    query = {
        "$or": [{
            "$and": [
                {
                    "send_user_id": user.id,
                    "receive_user_id": receive_user.id,
                    "time": {"$gte": datetime.now().timestamp() - 60 * 60 * 24 * 7}
                }
            ],
        }, {
            "$and": [
                {
                    "send_user_id": receive_user.id,
                    "receive_user_id": user.id,
                    "time": {"$gte": datetime.now().timestamp() - 60 * 60 * 24 * 7}
                }
            ],
        }]
    }
    if agree:
        argee_status = 1
    else:
        argee_status = 2

    ret = mongo.db.user_relation_history.update(query, {"$set":{"status":argee_status}})
    if ret and ret.get("nModified") < 1:
        return {
            "errno": status.CODE_UPDATE_USER_RELATION_ERROR,
            "errmsg": message.update_user_relation_fail,
        }
    else:
        return {
            "errno": status.CODE_OK,
            "errmsg": message.update_success,
        }

@jsonrpc.method("Use.relation.history")
@jwt_required # 验证jwt
def history_relation():
    """查找好友关系历史记录"""
    current_user_id = get_jwt_identity()
    user = User.query.get(current_user_id)
    if user is None:
        return {
            "errno": status.CODE_NO_USER,
            "errmsg": message.user_not_exists,
        }

    query = {
        "$or":[
            {"send_user_id":user.id,"time": {"$gte": datetime.now().timestamp() - 60 * 60 * 24 * 7}},
            {"receive_user_id": user.id,"time": {"$gte": datetime.now().timestamp() - 60 * 60 * 24 * 7}},
        ]
    }
    document_list = mongo.db.user_relation_history.find(query,{"_id":0})
    data_list = []
    for document in document_list:
        if document.get("send_user_id") == user.id and document.get("status") == 0:
            document["status"] = (0,"已添加")
        elif document.get("receive_user_id") == user.id and document.get("status") == 0:
            document["status"] = (0, "等待通过")
        elif document.get("status") == 1:
            document["status"] = (1, "已通过")
        else:
            document["status"] = (2, "已拒绝")

        data_list.append(document)

    return {
        "errno": status.CODE_OK,
        "errmsg": message.ok,
        "data_list": data_list,
    }

@jsonrpc.method("User.friend.list")
@jwt_required # 验证jwt
def list_friend(page=1,limit=2):
    """好友列表"""
    current_user_id = get_jwt_identity()
    user = User.query.get(current_user_id)
    if user is None:
        return {
            "errno": status.CODE_NO_USER,
            "errmsg": message.user_not_exists,
        }

    pagination = UserRelation.query.filter(
        or_(
            and_(UserRelation.send_user == user.id),
            and_(UserRelation.receive_user == user.id),
        )
    ).paginate(page,per_page=limit)
    user_id_list = []
    for relation in pagination.items:
        if relation.send_user == user.id:
            user_id_list.append(relation.receive_user)
        else:
            user_id_list.append(relation.send_user)

    # 获取用户详细信息
    user_list = User.query.filter(User.id.in_(user_id_list)).all()
    friend_list = [{"avatar":user.avatar,"nickname":user.nickname,"id":user.id,"fruit":0,"fruit_status":0} for user in user_list]
    pages = pagination.pages
    return {
        "errno": status.CODE_OK,
        "errmsg": message.ok,
        "friend_list": friend_list,
        "pages": pages
    }

·models.py

from werkzeug.security import generate_password_hash, check_password_hash
from application.utils.models import BaseModel,db
class User(BaseModel):
    """用户基本信息"""
    __tablename__ = "mf_user"
    name = db.Column(db.String(255), index=True, comment="用户账户")
    _password = db.Column(db.String(255), comment="登录密码")
    _transaction_password = db.Column(db.String(255), comment="交易密码")
    nickname = db.Column(db.String(255), comment="用户昵称")
    age = db.Column(db.SmallInteger, comment="年龄")
    money = db.Column(db.Numeric(7,2), comment="账户余额")
    ip_address = db.Column(db.String(255), default="", index=True, comment="登录IP")
    intro = db.Column(db.String(500), default="", comment="个性签名")
    avatar = db.Column(db.String(255), default="", comment="头像url地址")
    sex = db.Column(db.SmallInteger, default=0, comment="性别")  # 0表示未设置,保密, 1表示男,2表示女
    email = db.Column(db.String(32), index=True, default="", nullable=False, comment="邮箱地址")
    mobile = db.Column(db.String(32), index=True, nullable=False, comment="手机号码")
    unique_id = db.Column(db.String(255), index=True, default="", comment="客户端唯一标记符")
    province = db.Column(db.String(255), default="", comment="省份")
    city = db.Column(db.String(255), default="", comment="城市")
    area = db.Column(db.String(255), default="", comment="地区")
    info = db.relationship('UserProfile', backref='user', uselist=False)

    @property
    def password(self):
        return self._password

    @password.setter
    def password(self, rawpwd):
        """密码加密"""
        self._password = generate_password_hash(rawpwd)

    def check_password(self, rawpwd):
        """验证密码"""
        return check_password_hash(self.password, rawpwd)

    @property
    def transaction_password(self):
        return self._transaction_password

    @transaction_password.setter
    def transaction_password(self, rawpwd):
        """密码加密"""
        self._transaction_password = generate_password_hash(rawpwd)

    def check_transaction_password(self, rawpwd):
        """验证密码"""
        return check_password_hash(self.transaction_password, rawpwd)

class UserProfile(BaseModel):
    """用户详情信息表"""
    __tablename__ = "mf_user_profile"
    user_id = db.Column(db.Integer,db.ForeignKey('mf_user.id'), comment="用户ID")
    education = db.Column(db.Integer, comment="学历教育")
    middle_school = db.Column(db.String(255), default="", comment="初中/中专")
    high_school = db.Column(db.String(255), default="", comment="高中/高职")
    college_school = db.Column(db.String(255), default="", comment="大学/大专")
    profession_cate = db.Column(db.String(255), default="", comment="职业类型")
    profession_info = db.Column(db.String(255), default="", comment="职业名称")
    position = db.Column(db.SmallInteger, default=0, comment="职位/职称")
    emotion_status = db.Column(db.SmallInteger, default=0, comment="情感状态")
    birthday =db.Column(db.DateTime, default="", comment="生日")
    hometown_province = db.Column(db.String(255), default="", comment="家乡省份")
    hometown_city = db.Column(db.String(255), default="", comment="家乡城市")
    hometown_area = db.Column(db.String(255), default="", comment="家乡地区")
    hometown_address = db.Column(db.String(255), default="", comment="家乡地址")
    living_province = db.Column(db.String(255), default="", comment="现居住省份")
    living_city = db.Column(db.String(255), default="", comment="现居住城市")
    living_area = db.Column(db.String(255), default="", comment="现居住地区")
    living_address = db.Column(db.String(255), default="", comment="现居住地址")

    def __repr__(self):
        return "<%s %s>" % (self.__class__.__name__, self.user.name)


class UserRelation(BaseModel):
    """用户关系"""
    __tablename__ = "mf_user_relation"
    relation_status_chioce = (
        (1,"好友"),
        (2,"关注"),
    )
    relation_type_chioce = (
        (1, "手机"),
        (2, "账号"),
        (3, "邮箱"),
        (4, "昵称"),
        (5, "群聊"),
        (6, "二维码邀请注册"),
    )
    send_user = db.Column(db.Integer, comment="用户1") # 主动构建关系的用户
    receive_user = db.Column(db.Integer, comment="用户2") # 接受关系请求的用户
    relation_type = db.Column(db.Integer, default=1, comment="构建关系类型")
    relation_status = db.Column(db.Integer, default=1, comment="关系状态")

    def __repr__(self):
        return "用户%s通过%s对%s进行了%s操作" % (self.send_user,self.relation_type, self.receive_user,self.status)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值