我的课程如下:
class DisplayArtwork(Document):
name = StringField(required=True)
email = EmailField(required=True)
country = StringField(required=True)
phone = StringField()
artname = StringField(required=True)
medium = StringField(required=True)
caption = StringField(required=True)
filename = StringField(required=True)
votes = ListField(EmailField())
published = DateTimeField(required=True)
然后我将
DisplayArtwork.objects
发送到 Flask/jinja2 模板中,如下所示:
@app.route("/gallery")
def gallery():
return render_template("gallery.html", artworks=DisplayArtwork.objects)
模板内部是一个 for 循环,它迭代所有
DisplayArtwork
:{% for artwork in artworks %}
我的问题是:我可以检查当前用户的电子邮件(
current_user.get_id()
)是否在ListField(EmailField())
内吗?
首先,我检查当前用户是否已通过身份验证,然后检查
artwork['votes'][current_user.get_id()]
是否已定义。
{% if current_user.is_authenticated %}
{% if artwork['votes'][current_user.get_id()] is defined%}
<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 %}
upvote()
函数的工作原理如下:
function upvote(filename) {
const formData = new FormData();
formData.append('filename', filename);
fetch('/upvote', {
method: 'post',
body: formData
});
upvotebutton = document.getElementById(filename);
if (!upvotebutton) {alert('Error: ${filename} button not found');}
if (upvotebutton.classList.contains('btn-outline-success')) {
upvotebutton.classList.remove('btn-outline-success');
upvotebutton.classList.add('btn-success');
upvotebutton.innerHTML = 'Upvotes: ' + (parseInt(upvotebutton.innerHTML.split(' ')[1]) + 1);
}
else 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);
}
}
然后由后端的此函数处理:
@app.route("/upvote", methods=["POST"])
def upvote():
if current_user.is_authenticated:
artwork = DisplayArtwork.objects(filename=request.form["filename"])
if artwork:
response = None
try:
artwork.update(pull__votes=current_user.get_id())
response = "downvoted"
except KeyError:
artwork.update(add_to_set__votes=[current_user.get_id()])
response = "upvoted"
return response, 200
return "Failed to upvote", 500
return "Login to upvote", 401
不幸的是,这总是显示用户没有投票。
如何使投票功能发挥作用?
我明白了!
这是我改变的。
首先,在jinja2模板中,我像这样检查了电子邮件:
{% if current_user.get_id() in artwork.votes %}
而不是{% if artwork['votes'][current_user.get_id()] is defined%}
。
接下来,我将点赞功能更改为这样:
@app.route("/upvote", methods=["POST"])
def upvote():
if current_user.is_authenticated:
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)
return "downvoted", 200
else:
artwork.update(add_to_set__votes=user_email)
return "upvoted", 200
return "Failed to upvote", 500
return "Login to upvote", 401
artwork.update(pull__votes=user_email)
不会抛出KeyError,所以我将其更改为手动检查电子邮件是否在列表中,然后决定要做什么。
我还忘记添加
.first()
来获取一件艺术品而不是列表。