Reputation: 583
Am building a flask app. I have posts and tags. When making a post, one can select many tags for the post (just like here is stack overflow). The problem now comes in where the post is to be edited. Due to the pre-existing values, I get a sqlalchemy.exc.IntegrityError
due to duplicate entries. I have tried removing the duplicate entries before committing to the database by
post.tags = list(set(post.tags.all()))
but it still brings the same error. Here is the view function for editing the post:
@home.route('/edit/<int:id>', methods=['GET', 'POST'])
@login_required
def edit_post(id):
post = Post.query.get_or_404(id)
if current_user != post.author and not current_user.can(Permission.ADMINISTER):
abort(403)
form = PostForm()
form.tag.choices = [(tag.id, tag.name) for tag in Tag.query.order_by('name')]
if form.validate_on_submit():
post.body = form.body.data
for id in form.tag.data:
post.tags.append(Tag.query.get(id))
db.session.commit()
return redirect(url_for('.view_post', id=post.id))
form.body.data = post.body
form.tag.choices = [(tag.id, tag.name) for tag in Tag.query.order_by('name')]
form.tag.data = post.tags.all()
return render_template('home/edit_post.html', form=form, title='Edit Post')
Kindly help me solve this or advise me on a better logic of doing this. Consider me a beginner.
Upvotes: 0
Views: 49
Reputation: 583
After numerous trials, I was able to implement the editing successfully. So first I queried for all categories in this table filtering with the post id (returns a list of tuples) eg [(62, 1), (62, 4)]. The tuple is (post_id, tag_id).
categories = db.Table('categories', db.Column('post_id', db.Integer, db.ForeignKey('posts.id'), primary_key=True), db.Column('tag_id', db.Integer, db.ForeignKey('tags.id'), primary_key=True))
Then I custom made a tuple which I used to implement an if condition where if that tuple(s) exists in the list from categories, it is ignored and only the unique one is committed to the database.
Here is the new view function:
@home.route('/edit/<int:id>', methods=['GET', 'POST'])
@login_required
def edit_post(id):
post = Post.query.get_or_404(id)
if current_user != post.author and not current_user.can(Permission.ADMINISTER):
abort(403)
form = PostForm()
form.tag.choices = [(tag.id, tag.name) for tag in Tag.query.order_by('name')]
if form.validate_on_submit():
post.body = form.body.data
# query the post-tag relationship for this post id
posttags = db.session.query(categories).filter_by(post_id=id).all()
for id in form.tag.data:
# custom tuple
if (post.id, id) not in posttags:
post.tags.append(Tag.query.get(id))
db.session.commit()
return redirect(url_for('.view_post', id=post.id))
form.body.data = post.body
form.tag.choices = [(tag.id, tag.name) for tag in Tag.query.order_by('name')]
form.tag.data = post.tags.all()
return render_template('home/edit_post.html', form=form, title='Edit Post')
Upvotes: 1