Bluelog项目中删除分类后报错


#1

在Bluelog项目完成后,删除分类会提示分类已删除,之后访问主页等页面后会报错。
jinja2.exceptions.UndefinedError: 'None' has no attribute 'id'
在加上debug信息删除分类提示:

SAWarning: DELETE statement on table 'category' expected to delete 1 row(s); 0 were matched.  Please set confirm_deleted_rows=False within the mapper configuration to prevent this warning.
  % (table.description, expected, rows_matched)

从上面分析得出,可能是分类删掉了,其下文章没有划分到默认分类上??
代码上基本与源码仓库对照过了,没有问题。
以下是部分主要代码

@admin_bp.route('/category/<int:category_id>/delete', methods=['POST'])
@login_required
def delete_category(category_id):
	category = Category.query.get_or_404(category_id)
	if category.id == 1:
		flash('You can not delete the default category.', 'warning')
		return redirect(url_for('blog.index'))	
	category.delete() # 调用category对象的delete()方法删除分类
	flash('Category deleted.', 'success')
	return redirect(url_for('admin.manage_category'))
@blog_bp.route('/category/<int:category_id>')
def show_category(category_id):
	category = Category.query.get_or_404(category_id)
	page = request.args.get('page', 1, type=int)
	per_page = current_app.config['BLUELOG_POST_PER_PAGE']
	pagination = Post.query.with_parent(category).order_by(Post.timestamp.desc()).paginate(page, per_page)
	posts = pagination.items
	return render_template('blog/category.html', category=category, pagination=pagination, posts=posts)
class Category(db.Model):
	id = db.Column(db.Integer, primary_key=True)
	name = db.Column(db.String(30), unique=True)
	posts = db.relationship('Post', back_populates='category')

	# 定义delete属性,删除分类后,该分类下的文章不会被删除,会放到默认分类中。
	def delete(self):
		default_category = Category.query.get(1)
		posts = self.posts[:]
		for post in posts:
			post.category = default_category
			db.session.delete(self)
			db.session.commit()

谢谢。


#2

不太清楚你的操作步骤。你是指像这样删除?

  1. flask run启动服务;管理员登录;进入Category管理页面;
  2. 随便选一个Category删除,确定,然后回到Home。

QQ%E6%88%AA%E5%9B%BE20190330233743

以上步骤没有出现你说的问题,Bug没有复现。


#3
	def delete(self):
		default_category = Category.query.get(1)
		posts = self.posts[:]
		for post in posts:
			post.category = default_category
			db.session.delete(self)
			db.session.commit()

这里代码有问题,后面两行要放在for循环外面。

def delete(self):
    default_category = Category.query.get(1)
    posts = self.posts[:]
    for post in posts:
        post.category = default_category
    db.session.delete(self)
    db.session.commit()

#4

从故障现象中,慢慢排查已经判断大概就是删除分类后造成,导致其下文章没有加入到default分类中导致的。
这段delete函数代码,我看了几遍,还与源码仓库对照都没看出来,db.session.delete()要放在for循环外面,哎哎。
非常感谢。非常感谢。