验证 current_user 是否已经在数据库中

Validate current_user if it is already in DB

我无法显示验证错误,只有 SQLAlchemy 的 IntegrityError

(sqlalchemy.exc.IntegrityError: (sqlite3.IntegrityError) UNIQUE 约束失败:Booking.username).

我在数据库中有两个表,一个是注册用户列表,另一个是登录用户列表,他们可以在其中通过 FlaskForm 和 RadioFields 预订时间。我想我在这个函数中有错误 def validate_booking (self)

我需要检查current_user是否已经预订了时间,然后他不能再预订

I moved validation function into LoginForm instead and this seems to be working. It validates before the user jumps into next booking page. Not exactly how I wanted having the validation in booking page though.

models.py

class User(db.Model, UserMixin):
    __tablename__ = 'Employees'
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(20), unique=True, nullable=False)
    code = db.Column(db.String(20), nullable=False)

    def __repr__(self):
        return f"User('{self.username}', '{self.code}')"


class Book(db.Model, UserMixin):
    __tablename__ = 'Booking'
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(20), unique=True, nullable=False)
    choice = db.Column(db.String(30), nullable=False)

    def __repr__(self):
        return f"Book('{self.username}, '{self.choice}')"

forms.py

    class LoginForm(FlaskForm):
        username = StringField('Name', validators=[DataRequired(), Length(min=2, max=20)])
        code = StringField('Code', validators=[DataRequired()])
        submit = SubmitField('Book time')

        def validate_username(self, username):
            user = Book.query.filter_by(username=username.data).first()
            if user:
                raise ValidationError('You have registered your car today')
    
    class BookingForm(FlaskForm):
        book = RadioField('Label', choices=[('Station_1_morning', '07:00-11:00'), ('Station_1_afternoon', '11:00-15:00'),
                                            ('Station_2_morning', '07:00-11:00'), ('Station_2_afternoon', '11:00-15:00'),
                                            ('Station_3_morning', '07:00-11:00'), ('Station_3_afternoon', '11:00-15:00')],
                          coerce=str, validators=[InputRequired()])
        submit = SubmitField('Register time')
    
        

routes.py

@app.route("/booking", methods=['POST', 'GET'])
@login_required
def booking():
    session.permanent = True
    app.permanent_session_lifetime = timedelta(seconds=5)
    form = BookingForm()
    if form.validate_on_submit():
        book = Book(username=current_user.username, choice=form.book.data)
        db.session.add(book)
        db.session.commit()
        flash('Your time is registered', 'success')
    return render_template('booking.html', title='Booking', form=form)

我没有看到错误。您可以在验证函数中添加一个 print (user) 以查看其中的内容。

无论如何,这仍然存在竞争条件:如果同一用户在检查(“验证”)和提交之间的另一个请求中预订。作为一般规则,我宁愿尝试提交并捕获完整性错误。从完整性错误异常对象构建有意义的消息可能有点棘手(我的意思是从对象中获取违规字段的名称)。当然,如果您确定只有一个约束适用,您可以对消息进行硬编码。