python - 在 Flask 和 Flask SQLAlchemy 中处理重复用户
问题描述
我想允许匿名用户在博客中发表他们的评论,而不需要他们登录或注册。一位匿名用户可以在后续访问期间使用相同的凭据发布多条评论。但是,我SQLAlchemy IntegrityError
在第二次尝试时得到了。
我有一个简单的表格,一个简单的模型和一个基本的路线。
comment.py
class CommentForm(FlaskForm):
username = StringField('Username', validators=[DataRequired()])
email = StringField('Email', validators=[DataRequired(), Email()])
comment = TextAreaField('Comment', validators=[DataRequired()])
submit = SubmitField('Post')
models.py
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(64), index=True, unique=True)
email = db.Column(db.String(120), index=True, unique=True)
posts = db.relationship('Post', backref='author', lazy='dynamic')
class Post(db.Model):
id = db.Column(db.Integer, primary_key=True)
body = db.Column(db.String(500))
timestamp = db.Column(db.DateTime, index=True, default=datetime.utcnow)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
route.py
@app.route('/personal_blog', methods = ['GET', 'POST'])
def personal_blog():
form = CommentForm()
if form.validate_on_submit():
user = User(username = form.username.data, email = form.email.data)
post = Post(body = form.comment.data, author = user)
db.session.add(user)
db.session.add(post)
db.session.commit()
flash('Your comment is now live!')
return redirect(url_for('personal_blog', _anchor='translate-hover'))
posts = Post.query.order_by(Post.timestamp.desc()).all()
return render_template('personal_blog.html', form = form, posts = posts)
我尝试了几种建议的解决方案,而我来到的壁橱是向表单添加验证,例如:
class CommentForm(FlaskForm):
username = StringField('Username', validators=[DataRequired()])
email = StringField('Email', validators=[DataRequired(), Email()])
comment = TextAreaField('Comment', validators=[DataRequired()])
submit = SubmitField('Post')
def __init__(self, original_username, *args, **kwargs):
super(CommentForm, self).__init__(*args, **kwargs)
self.original_username = original_username
def validate_username(self, username):
if username.data != self.original_username:
user = User.query.filter_by(username=self.username.data).first()
if user is not None:
raise ValidationError('Please use a different username.')
但是,这需要添加@app.route('/personal_blog/<username>')
它基本上不适用于我的情况。我想让这个匿名用户发布后续评论,而无需更改用户名或电子邮件。
就个人而言,我尝试在路由 ( if user.username is not None: flash('Use different credentials!')
) 中添加验证,以通知用户他们尝试使用的电子邮件或用户名已被使用,并且它有效,但这不是我希望应用程序执行的操作。用户可以简单地使用与以前完全相同的凭据。如何做到这一点?
解决方案
解决方案是从表中删除unique
约束。User
代替:
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(64), index=True, unique=True) <----------here
email = db.Column(db.String(120), index=True, unique=True) <----------here
posts = db.relationship('Post', backref='author', lazy='dynamic')
我有这个:
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(64), index=True) <----------here
email = db.Column(db.String(120), index=True) <----------here
posts = db.relationship('Post', backref='author', lazy='dynamic')
一旦我更新数据库,更改就会生效,并且我可以允许单个匿名用户使用相同的凭据发布多个评论。
推荐阅读
- r - 基于具有分类和定量值的多边形和栅格的数据提取
- java - 接口 javax.transaction.Transaction 的实现是否需要线程安全?
- python-2.7 - pdf python报告实验室中的右对齐数字
- javascript - 如何在 ReactJs 中制作步骤向导表单?
- python - '您无权在此位置保存。联系管理员以获得权限'我是计算机上的唯一管理员
- html - 根据父 div 裁剪背景图像
- python - 如何使用 collocation() 将其存储为列表
- ios - 如何在导航栏中使用 prefersLargeTitles 创建左对齐标题?
- prometheus - Prometheus+grafana:如何绘制每个时隙的事件
- javascript - 我正在制作一个刽子手游戏,我把逻辑搞砸了,但它不起作用,当我检查它时,它说 undefined touppercase