FLASK SQlite Python-检查用户名是否已在数据库中

FLASK SQlite Python-检查用户名是否已在数据库中,python,sqlite,Python,Sqlite,嘿,有人能告诉我我的代码哪里做错了吗?我想检查数据库中是否已经有用户名 #Models class User(UserMixin, db.Model): id = db.Column(db.Integer, primary_key=True, autoincrement=True) username = db.Column(db.String(15), unique=True, nullable=False) email = db.Column(db.String(50)

嘿,有人能告诉我我的代码哪里做错了吗?我想检查数据库中是否已经有用户名

#Models
class User(UserMixin, db.Model):
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    username = db.Column(db.String(15), unique=True, nullable=False)
    email = db.Column(db.String(50), unique=True, nullable=False)
    password = db.Column(db.String(120), unique=True, nullable=False)
    created_on = db.Column(db.DateTime, server_default=db.func.now())
    updated_on = db.Column(db.DateTime, server_default=db.func.now(), server_onupdate=db.func.now())
    tasks = db.relationship('Task', backref='author', lazy='dynamic')

    @classmethod
    def is_user_name_taken(cls, username):
      return db.session.query(db.exists().where(User.username==username)).scalar()

    @classmethod
    def is_email_taken(cls, email):
      return db.session.query(db.exists().where(User.email==email)).scalar()

    def __repr__(self):
        return '<User %r>' % (self.username)

#User Signup Api
@app.route('/todo/api/v1.0/signup', methods=['POST'])
def signup():

    if 'username' not in request.json:
        return jsonify({'username': 'must include username'})
    if 'email' not in request.json:
        return jsonify({'email': 'must include email'})
    if 'password' not in request.json:
        return jsonify({'password' : 'must include password' })

    if User.is_user_name_taken(request.json['username']):
         return jsonify({'username': 'This username is already taken!'}), 409
    if User.is_email_taken(request.json['email']):
         return jsonify({'email': 'This email is already taken!'}), 409

    if request.json :
        hashed_password = generate_password_hash(request.json['password'], method='sha256')
        new_user = User(username=request.json['username'], email=request.json['email'], password=hashed_password)
        db.session.add(new_user)
        db.session.commit()
        return jsonify({'user': 'user created successfully'}), 201
    return jsonify({'username': 'must include username', 
            'password': 'must include password', 
            'email' : 'must include email' })
全程。它不会给我任何错误,但也不会填满我的数据库

@app.route('/regist', methods=['GET', 'POST'])
def regist():
    if request.method == "POST":
        with sql.connect("database.db") as con:
            cur = con.cursor()
        try:
            # flash("register attempted")

            username = request.form['username']
            password = request.form['password']
            passwordencr = request.form['password']
            email = request.form['email']

            x = cur.execute("SELECT * FROM users WHERE name = ?", (username))

            if int(len(x)) > 0:
                flash("That username is already taken, please choose another")
                return render_template('register.html')
            else:
                cur.execute("INSERT INTO users (name,password,email) VALUES (?,?,?)",(username,passwordencr,email) )

                con.commit()
                flash ("Successfully registrated")
        except:
            con.rollback()
            msg = "error in insert operation"

        finally:
            session['logged_in'] = True
            session['username'] = username
            gc.collect()
            msg = Message('Hello', sender='yourId@gmail.com', recipients=[email])
            msg.body = "your username for ak047 is: %s and your password is %s" %(username,password)
            mail.send(msg)
            return render_template("home.html", msg=msg)
            con.close()
            gc.collect()

此代码在第1行和第9行两次连接到
数据库.db
。可能这不是最初的意图

此代码在第1行和第9行两次连接到
数据库.db。可能这不是最初打算的

首先,我想我有一个针对原始问题的工作代码示例。但是,我认为使用数据库中的约束可以更好地解决这个重复用户问题。请看我答案的底部

首先,让我们检查当前代码。我可以在这里看到几个问题:

  • try/finally
    的缩进不正确表示在
    try/finally
    期间没有活动的连接
  • 检查是否有用户名的条目的方式不正确
  • 缩进

    在当前代码中,第6行的
    try/finally
    块需要进一步缩进,以便能够使用第4行的
    with
    语句中建立的连接

    按照代码当前的状态,连接在使用时已经关闭,因此所有数据库访问都将失败

    正在检查用户

    用于检查用户的代码将失败,抛出一个异常,该异常将导致命中finally并执行
    回滚。调用
    len
    时,无论是否存在任何条目,
    execute
    的返回值都会引发异常

    下面是我从python shell中获得的内容,以说明我的意思:

    >>> int(len(cur.execute("select * from people where name_last=:who", {"who": "mike"})))
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: object of type 'sqlite3.Cursor' has no len()
    
    因此,我认为这样做可能会奏效:

    def regist():
        if request.method == "POST":
            with sql.connect("database.db") as con:
                cur = con.cursor()
                try:
                    # ... Collecting form info ...
    
                    cur.execute("SELECT * FROM users WHERE name = ?", (username))
    
                    if cur.fetchone() is not None:
                        flash("That username is already taken...")
                        return render_template('register.html')
                    else:
                        cur.execute("INSERT INTO users (name,password,email) VALUES (?,?,?)",(username,passwordencr,email) )
                        con.commit()
                        flash (...)
                 except:
                     con.rollback()
    
                 finally:
                     session['logged_in'] = True
                     session['username'] = username
                     # ... mailing code ...
    
    替代方法

    更可靠的方法是让数据库负责防止重复用户

    创建表时,使
    名称
    唯一
    。然后插入具有相同用户名的记录将引发异常。以以下表格为例:


    首先,我想我有一个原始问题的工作代码示例。但是,我认为使用数据库中的约束可以更好地解决这个重复用户问题。请看我答案的底部

    首先,让我们检查当前代码。我可以在这里看到几个问题:

  • try/finally
    的缩进不正确表示在
    try/finally
    期间没有活动的连接
  • 检查是否有用户名的条目的方式不正确
  • 缩进

    在当前代码中,第6行的
    try/finally
    块需要进一步缩进,以便能够使用第4行的
    with
    语句中建立的连接

    按照代码当前的状态,连接在使用时已经关闭,因此所有数据库访问都将失败

    正在检查用户

    用于检查用户的代码将失败,抛出一个异常,该异常将导致命中finally并执行
    回滚。调用
    len
    时,无论是否存在任何条目,
    execute
    的返回值都会引发异常

    下面是我从python shell中获得的内容,以说明我的意思:

    >>> int(len(cur.execute("select * from people where name_last=:who", {"who": "mike"})))
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: object of type 'sqlite3.Cursor' has no len()
    
    因此,我认为这样做可能会奏效:

    def regist():
        if request.method == "POST":
            with sql.connect("database.db") as con:
                cur = con.cursor()
                try:
                    # ... Collecting form info ...
    
                    cur.execute("SELECT * FROM users WHERE name = ?", (username))
    
                    if cur.fetchone() is not None:
                        flash("That username is already taken...")
                        return render_template('register.html')
                    else:
                        cur.execute("INSERT INTO users (name,password,email) VALUES (?,?,?)",(username,passwordencr,email) )
                        con.commit()
                        flash (...)
                 except:
                     con.rollback()
    
                 finally:
                     session['logged_in'] = True
                     session['username'] = username
                     # ... mailing code ...
    
    替代方法

    更可靠的方法是让数据库负责防止重复用户

    创建表时,使
    名称
    唯一
    。然后插入具有相同用户名的记录将引发异常。以以下表格为例:


    做一个功能,检查用户名和电子邮件是否已经在数据库中

    #Models
    class User(UserMixin, db.Model):
        id = db.Column(db.Integer, primary_key=True, autoincrement=True)
        username = db.Column(db.String(15), unique=True, nullable=False)
        email = db.Column(db.String(50), unique=True, nullable=False)
        password = db.Column(db.String(120), unique=True, nullable=False)
        created_on = db.Column(db.DateTime, server_default=db.func.now())
        updated_on = db.Column(db.DateTime, server_default=db.func.now(), server_onupdate=db.func.now())
        tasks = db.relationship('Task', backref='author', lazy='dynamic')
    
        @classmethod
        def is_user_name_taken(cls, username):
          return db.session.query(db.exists().where(User.username==username)).scalar()
    
        @classmethod
        def is_email_taken(cls, email):
          return db.session.query(db.exists().where(User.email==email)).scalar()
    
        def __repr__(self):
            return '<User %r>' % (self.username)
    
    #User Signup Api
    @app.route('/todo/api/v1.0/signup', methods=['POST'])
    def signup():
    
        if 'username' not in request.json:
            return jsonify({'username': 'must include username'})
        if 'email' not in request.json:
            return jsonify({'email': 'must include email'})
        if 'password' not in request.json:
            return jsonify({'password' : 'must include password' })
    
        if User.is_user_name_taken(request.json['username']):
             return jsonify({'username': 'This username is already taken!'}), 409
        if User.is_email_taken(request.json['email']):
             return jsonify({'email': 'This email is already taken!'}), 409
    
        if request.json :
            hashed_password = generate_password_hash(request.json['password'], method='sha256')
            new_user = User(username=request.json['username'], email=request.json['email'], password=hashed_password)
            db.session.add(new_user)
            db.session.commit()
            return jsonify({'user': 'user created successfully'}), 201
        return jsonify({'username': 'must include username', 
                'password': 'must include password', 
                'email' : 'must include email' })
    
    #模型
    类用户(UserMixin,db.Model):
    id=db.Column(db.Integer,主键=True,自动递增=True)
    username=db.Column(db.String(15),unique=True,nullable=False)
    email=db.Column(db.String(50),unique=True,nullable=False)
    password=db.Column(db.String(120),unique=True,nullable=False)
    已创建\u on=db.Column(db.DateTime,server\u default=db.func.now())
    更新了\u on=db.Column(db.DateTime,server\u default=db.func.now(),server\u onupdate=db.func.now())
    tasks=db.relationship('Task',backref='author',lazy='dynamic')
    @类方法
    def为用户名称(cls,用户名):
    返回db.session.query(db.exists().where(User.username==username)).scalar()
    @类方法
    def已通过电子邮件发送(cls,电子邮件):
    返回db.session.query(db.exists().where(User.email==email)).scalar()
    定义报告(自我):
    返回“”%(self.username)
    #用户注册Api
    @app.route('/todo/api/v1.0/signup',methods=['POST'])
    def signup():
    如果request.json中没有“username”:
    返回jsonify({'username':'必须包含username'})
    如果request.json中没有“email”:
    返回jsonify({'email':'必须包含email'})
    如果request.json中没有“password”:
    返回jsonify({'password':'必须包含密码'})
    如果使用User.is_User_name_(request.json['username']):
    返回jsonify({'username':'此用户名已被使用!'),409
    如果使用User.is_email(request.json['email']):
    返回jsonify({'email':'此电子邮件已被接收!'),409
    如果是request.json:
    hashed_password=generate_password_hash(request.json['password'],method='sha256')
    new_user=user(username=request.json['username'],email=request.json['email'],password=hash_密码)
    db.session.add(新用户)
    db.session.commit()
    返回jsonify({'user':'user created successfully'}),201
    返回jsonify({'username':'必须包含用户名',
    “密码”:“必须包含密码”,
    “email”:“m”