如何在Jinja2模板中判断用户邮箱是否在ListField(EmailField)中?
修复投票功能的方案
一、修复模板中的点赞状态判断逻辑
原模板中用字典索引的方式判断点赞状态是错误的(votes是列表而非字典),需改为用in操作符检查用户邮箱是否在列表中:
{% if current_user.is_authenticated %} {% if current_user.get_id() in artwork.votes %} <button id="{{ artwork.filename }}" type="button" class="btn btn-success" onclick='upvote(`{{ artwork.filename }}`)'>Upvotes: {{ artwork.votes|length }}</button> {% else %} <button id="{{ artwork.filename }}" type="button" class="btn btn-outline-success" onclick='upvote(`{{ artwork.filename }}`)'>Upvotes: {{ artwork.votes|length }}</button> {% endif %} {% else %} <a href="/login" class="btn btn-success">Login to Upvote</a> {% endif %}
二、修复后端的投票处理逻辑
- 原代码中
DisplayArtwork.objects(filename=...)返回的是QuerySet而非单个对象,需用.first()获取匹配的单个作品 - 原
try-except逻辑无效(MongoEngine的pull操作不会因元素不存在抛出KeyError),需先判断用户是否已点赞再执行对应操作:
@app.route("/upvote", methods=["POST"]) def upvote(): if current_user.is_authenticated: # 获取单个匹配的作品对象,而非QuerySet artwork = DisplayArtwork.objects(filename=request.form["filename"]).first() if artwork: user_email = current_user.get_id() if user_email in artwork.votes: # 已点赞,取消点赞 artwork.update(pull__votes=user_email) response = "downvoted" else: # 未点赞,添加点赞 artwork.update(add_to_set__votes=user_email) response = "upvoted" return response, 200 return "Failed to upvote", 500 return "Login to upvote", 401
三、优化前端fetch逻辑(可选)
原前端未处理请求错误,添加响应和错误处理避免状态不同步:
function upvote(filename) { const formData = new FormData(); formData.append('filename', filename); const upvotebutton = document.getElementById(filename); if (!upvotebutton) { alert(`Error: ${filename} button not found`); return; } fetch('/upvote', { method: 'post', body: formData }) .then(response => { if (!response.ok) throw new Error('Network response was not ok'); return response.text(); }) .then(result => { if (result === "upvoted") { upvotebutton.classList.remove('btn-outline-success'); upvotebutton.classList.add('btn-success'); upvotebutton.innerHTML = 'Upvotes: ' + (parseInt(upvotebutton.innerHTML.split(' ')[1]) + 1); } else if (result === "downvoted") { upvotebutton.classList.remove('btn-success'); upvotebutton.classList.add('btn-outline-success'); upvotebutton.innerHTML = 'Upvotes: ' + (parseInt(upvotebutton.innerHTML.split(' ')[1]) - 1); } }) .catch(error => { console.error('Upvote error:', error); alert('Upvote failed, please try again'); // 还原按钮状态 if (upvotebutton.classList.contains('btn-success')) { upvotebutton.classList.remove('btn-success'); upvotebutton.classList.add('btn-outline-success'); upvotebutton.innerHTML = 'Upvotes: ' + (parseInt(upvotebutton.innerHTML.split(' ')[1]) - 1); } else { upvotebutton.classList.remove('btn-outline-success'); upvotebutton.classList.add('btn-success'); upvotebutton.innerHTML = 'Upvotes: ' + (parseInt(upvotebutton.innerHTML.split(' ')[1]) + 1); } }); }
内容的提问来源于stack exchange,提问作者wenbang
相关产品推荐
相关产品推荐

