2016-10-23 71 views
0

嘿,任何人都可以告訴我,我在我的代碼中做錯了什麼?我想檢查用戶名是否已經在數據庫中。FLASK SQlite Python - 檢查用戶名是否已經在數據庫中

整個路線。它不會給我任何錯誤,但也不會填補我的數據庫。

@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='[email protected]', 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() 
+0

我覺得你的代碼肯定是錯誤的,你不應該使用,除非你有一個毯子,如果你沒有,你會看到你的錯誤 –

+0

你並不需要調用'INT(LEN(X) )'。 'len'返回一個整數。你也不需要比較0的長度。'如果len(x)> 0'和'if x'相同。 – dirn

回答

3

首先,我認爲我有原問題工作代碼示例。不過,我認爲你可以使用數據庫中的約束來更好地解決這個重複的用戶問題。看到我的答案的底部。

首先讓我們來檢查當前的代碼。有一對夫婦的問題,我可以在這裏看到:

  1. try/finally不正確的縮進表示還有的try/finally期間沒有連接活躍。
  2. 您檢查用戶名是否有條目的方式不正確。

縮進

在當前的代碼,在第6個的需求try/finally塊被縮進一個進一步爲了能夠使用通過在上線with語句進行的連接建立的連接4.

由於目前的代碼,連接在使用時會關閉,因此所有數據庫訪問都將失敗。

檢查用戶

用於檢查用戶將失敗的代碼,拋出異常,這將導致最終被命中和rollback被執行。當您致電len時,從execute返回的值會引發異常,無論是否有任何條目。

這是我從一個Python殼去說明我的意思:

>>> 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() 

相反,要檢查select語句是否返回一個值,使用fetchone,看看它是否返回None

# No users named `fred`: 
>>> cur.execute("select * from people where name_last=:who", {"who": "fred"}) 
<sqlite3.Cursor object at 0x10bbd0180> 
>>> cur.fetchone() is None 
True 

# At least one user named `mike`: 
>>> cur.execute("select * from people where name_last=:who", {"who": "mike"}) 
<sqlite3.Cursor object at 0x10bbd0180> 
>>> cur.fetchone() is None 
False 

我思故這樣的事情可能工作:

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 ... 

替代方法

更健壯的方法是讓數據庫負責防止重複的用戶。

創建表時創建nameunique。然後用相同的用戶名插入一條記錄會引發異常。以一個例子來自sqlite3 docs

import sqlite3 

con = sqlite3.connect(":memory:") 
con.execute("create table person (id integer primary key, firstname varchar unique)") 

# Successful, con.commit() is called automatically afterwards 
with con: 
    con.execute("insert into person(firstname) values (?)", ("Joe",)) 

# con.rollback() is called after the with block finishes with an exception, the 
# exception is still raised and must be caught 
try: 
    with con: 
     con.execute("insert into person(firstname) values (?)", ("Joe",)) 
except sqlite3.IntegrityError: 
    print "couldn't add Joe twice" 
+0

http://prntscr.com/cxyunv是這樣的?我很困惑。 – Julian

+0

更新的代碼,希望能夠清楚我的意思:) –

+0

它仍然不會填滿我的數據庫。我想說的是:當我刪除它在數據庫中檢查用戶名的部分(如果它已經存在),我的代碼完美工作,並填充我的數據庫.. – Julian

0

這段代碼的行1和9連接到database.db兩次也許這不是最初的目的是

+0

它不會給我任何錯誤,但信息仍然不會傳遞到數據庫中。 – Julian

+0

我把我的代碼放在頂部。如果你可以看看它會很友善。 – Julian

+0

我認爲@邁克羅德斯是正確的,嘗試/除了塊應該縮進一個級別 – Marat

2

製作一個功能,誰檢查用戶名和電子郵件已經在數據庫或沒有。

#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' }) 
相關問題