通过 django 模板和 JS 动态喜欢和不喜欢按钮的问题
Problems with dynamic like and dislike buttons via django templates and JS
我正在尝试为我的 cs50w 项目动态创建和使用喜欢和不喜欢的按钮,这当然应该允许用户喜欢或不喜欢 post 并将喜欢的按钮切换到不喜欢的按钮和很快。现在,令人气愤的是,类似和不同的机制本身都可以工作,但按钮却让我很不爽。
- 要么我删除后无法创建相反的按钮
通过 Javascript 的原始版本(我尝试使用
appendChild
和 CreateElement
,无济于事)。
- 或者如果 post 有超过 1 个赞,那么会出现更多按钮,其中 2/3 是无用的,等等。
我在 Django 视图中检查当前用户是否喜欢任何 posts(喜欢在他们自己的模型中有 2 个外键),然后如果有任何 posts 然后我将它们作为上下文发送到必要的模板。
在模板本身内部,我检查 post 是否对应于上下文,如果是,我生成一个 Unlike 按钮,如果不是,我生成一个 Like 按钮。我进行了修补和谷歌搜索,但情况根本没有改善...
代码:
index.html:
{% extends "network/layout.html" %}
{{ user.username|json_script:"username" }}
{% block body %}
<h3 id='greeting'>Brand new posts! Just for you</h3>
{% for page in pages %}
<div class="card border-primary post">
<h5 class="card-header bg-info user_link">{{page.user.username}}</h5>
<div class="card-body">
<div class="card-text border-success" id="content">{{page.content}}</div>
{% if user.is_authenticated %}
{% if user.username == page.user.username %}
<div class="card-text border-success" id='edit-controls'>
<textarea id="edit-content"></textarea>
<button class="btn btn-primary" id='save-edit'>Save Edit</button>
</div>
<button class="btn btn-primary edit">Edit Post</button>
{% endif %}
{% endif %}
</div>
<div class="card-footer">
<p id='page_id' style="display: none;">{{page.id}}</p>
<div class="card-text" id='created_on'>Posted on: {{page.created_on}}</div>
<span class="card-text" id='likes'>{{page.likes}} people have liked this</span>
{% if user.is_authenticated %}
{% for like in liked %}
{% if like.liked_post == page %}
<span><button class="btn btn-secondary" id="unlike">Unlike</button></span>
{% endif %}
{% if like.liked_post != page %}
<span><button class="btn btn-secondary" id="like">Like</button></span>
{% endif %}
{% empty %}
<span><button class="btn btn-secondary" id="like">Like</button></span>
{% endfor %}
{% endif %}
</div>
</div>
{% endfor %}
<div class="container p-4">
<div class="pagination justify-content-center">
<span class="step-links">
{% if pages.has_previous %}
<a href="?page=1">« first</a>
<a href="?page={{ pages.previous_page_number }}">previous</a>
{% endif %}
<span class="current">
Page {{ pages.number }} of {{ pages.num_pages }}
</span>
{% if pages.has_next %}
<a href="?page={{ pages.next_page_number }}">next</a>
<a href="?page={{ pages.num_pages }}">last »</a>
{% endif %}
</span>
</div>
</div>
{% endblock %}
网络。js/liking函数
function liking()
{
const divs = document.querySelectorAll(".card-footer");
divs.forEach((div) => {
const like_btn = div.querySelector('#like');
const unlike_btn = div.querySelector("#unlike");
const page_id = div.querySelector("#page_id");
if (like_btn !== null)
{
like_btn.onclick = () => {
const like_str = div.querySelector("#likes").textContent;
let like_amount = parseInt(like_str.substring(0));
like_amount++;
div.querySelector("#likes").textContent = `${like_amount.toString()} people have liked this`;
like_btn.remove();
like(page_id.textContent, "like");
};
}
if (unlike_btn !== null)
{
unlike_btn.onclick = () => {
const like_str = div.querySelector("#likes").textContent;
let like_amount = parseInt(like_str.substring(0));
if (like_amount > 0)
{
like_amount--;
div.querySelector("#likes").textContent = `${like_amount.toString()} people have liked this`;
}
else if (like_amount === 0)
{
like_amount = 0;
div.querySelector("#likes").textContent = `0 people have liked this`;
}
unlike_btn.remove();
like(page_id.textContent, "unlike");
};
}
});
}
喜欢模特
class Like(models.Model):
user = models.ForeignKey(User, on_delete=CASCADE)
liked_post = models.ForeignKey(Post, on_delete=CASCADE)
def __str__(self):
return f"{self.id} - Post {self.liked_post} liked by {self.user}"
def is_valid_like(self):
return self.user != None and self.liked_post != None
我使用的 django 视图:
def index(request):
posts = Post.objects.all().order_by('-id')
pages = Paginator(posts, 10)
page_num = request.GET.get('page')
page_obj = pages.get_page(page_num)
try:
user_info = User.objects.get(username=request.user.username)
except User.DoesNotExist:
user_info=None
liked_posts = None
liked_posts = Like.objects.filter(user=user_info)
print(liked_posts)
return render(request, "network/index.html", {
"pages": page_obj,
"liked": liked_posts
})
def render_profile(request, username):
if request.method == "GET":
user_info = None
try:
user_info = User.objects.get(username=username)
except Error:
return render(request, "network/notfound.html")
posts = Post.objects.filter(user=user_info).reverse()
followers = Follow.objects.filter(followee=user_info).count()
follows = Follow.objects.filter(user=user_info).count()
is_following = True
try:
Follow.objects.get(user=request.user, followee=user_info)
except Follow.DoesNotExist:
is_following = False
liked_posts = Like.objects.filter(user=user_info)
print(liked_posts)
JsonResponse({"found": "profile has been found"}, status=200)
pages = Paginator(posts, 10)
page_num = request.GET.get('page')
page_obj = pages.get_page(page_num)
return render(request, "network/profile.html", {
"username": user_info.username,
"pages": page_obj,
"followers": followers,
"follows": follows,
"following": is_following,
"liked": liked_posts
})
我在另一个论坛上得到了这个答案。
在index.html
代码:
{% if user.is_authenticated %}
{% for like in liked %}
{% if like.liked_post == page %}
<span class="is-liked-unlike"><button class="btn btn-secondary" id="unlike">Unlike</button></span>
<span class="is-liked-like"><button class="btn btn-secondary" style="display:none"
id="like">Like</button></span>
{% endif %}
{% endfor %}
<span class="is-not-liked-likeBtn"><button class="btn btn-secondary" id="like">Like</button></span>
<span class="is-not-liked-unlikedBtn"><button class="btn btn-secondary" id="unlike"
style="display:none">Unlike</button></span>
{% endif %}
在network.js中,在divs.forEach中:
代码:
div.querySelectorAll(".is-liked-unlike").forEach((unliked) => {
unliked.nextElementSibling.nextElementSibling.remove();
unliked.nextElementSibling.nextElementSibling.remove();
});
我正在尝试为我的 cs50w 项目动态创建和使用喜欢和不喜欢的按钮,这当然应该允许用户喜欢或不喜欢 post 并将喜欢的按钮切换到不喜欢的按钮和很快。现在,令人气愤的是,类似和不同的机制本身都可以工作,但按钮却让我很不爽。
- 要么我删除后无法创建相反的按钮
通过 Javascript 的原始版本(我尝试使用
appendChild
和CreateElement
,无济于事)。 - 或者如果 post 有超过 1 个赞,那么会出现更多按钮,其中 2/3 是无用的,等等。
代码: index.html:
{% extends "network/layout.html" %}
{{ user.username|json_script:"username" }}
{% block body %}
<h3 id='greeting'>Brand new posts! Just for you</h3>
{% for page in pages %}
<div class="card border-primary post">
<h5 class="card-header bg-info user_link">{{page.user.username}}</h5>
<div class="card-body">
<div class="card-text border-success" id="content">{{page.content}}</div>
{% if user.is_authenticated %}
{% if user.username == page.user.username %}
<div class="card-text border-success" id='edit-controls'>
<textarea id="edit-content"></textarea>
<button class="btn btn-primary" id='save-edit'>Save Edit</button>
</div>
<button class="btn btn-primary edit">Edit Post</button>
{% endif %}
{% endif %}
</div>
<div class="card-footer">
<p id='page_id' style="display: none;">{{page.id}}</p>
<div class="card-text" id='created_on'>Posted on: {{page.created_on}}</div>
<span class="card-text" id='likes'>{{page.likes}} people have liked this</span>
{% if user.is_authenticated %}
{% for like in liked %}
{% if like.liked_post == page %}
<span><button class="btn btn-secondary" id="unlike">Unlike</button></span>
{% endif %}
{% if like.liked_post != page %}
<span><button class="btn btn-secondary" id="like">Like</button></span>
{% endif %}
{% empty %}
<span><button class="btn btn-secondary" id="like">Like</button></span>
{% endfor %}
{% endif %}
</div>
</div>
{% endfor %}
<div class="container p-4">
<div class="pagination justify-content-center">
<span class="step-links">
{% if pages.has_previous %}
<a href="?page=1">« first</a>
<a href="?page={{ pages.previous_page_number }}">previous</a>
{% endif %}
<span class="current">
Page {{ pages.number }} of {{ pages.num_pages }}
</span>
{% if pages.has_next %}
<a href="?page={{ pages.next_page_number }}">next</a>
<a href="?page={{ pages.num_pages }}">last »</a>
{% endif %}
</span>
</div>
</div>
{% endblock %}
网络。js/liking函数
function liking()
{
const divs = document.querySelectorAll(".card-footer");
divs.forEach((div) => {
const like_btn = div.querySelector('#like');
const unlike_btn = div.querySelector("#unlike");
const page_id = div.querySelector("#page_id");
if (like_btn !== null)
{
like_btn.onclick = () => {
const like_str = div.querySelector("#likes").textContent;
let like_amount = parseInt(like_str.substring(0));
like_amount++;
div.querySelector("#likes").textContent = `${like_amount.toString()} people have liked this`;
like_btn.remove();
like(page_id.textContent, "like");
};
}
if (unlike_btn !== null)
{
unlike_btn.onclick = () => {
const like_str = div.querySelector("#likes").textContent;
let like_amount = parseInt(like_str.substring(0));
if (like_amount > 0)
{
like_amount--;
div.querySelector("#likes").textContent = `${like_amount.toString()} people have liked this`;
}
else if (like_amount === 0)
{
like_amount = 0;
div.querySelector("#likes").textContent = `0 people have liked this`;
}
unlike_btn.remove();
like(page_id.textContent, "unlike");
};
}
});
}
喜欢模特
class Like(models.Model):
user = models.ForeignKey(User, on_delete=CASCADE)
liked_post = models.ForeignKey(Post, on_delete=CASCADE)
def __str__(self):
return f"{self.id} - Post {self.liked_post} liked by {self.user}"
def is_valid_like(self):
return self.user != None and self.liked_post != None
我使用的 django 视图:
def index(request):
posts = Post.objects.all().order_by('-id')
pages = Paginator(posts, 10)
page_num = request.GET.get('page')
page_obj = pages.get_page(page_num)
try:
user_info = User.objects.get(username=request.user.username)
except User.DoesNotExist:
user_info=None
liked_posts = None
liked_posts = Like.objects.filter(user=user_info)
print(liked_posts)
return render(request, "network/index.html", {
"pages": page_obj,
"liked": liked_posts
})
def render_profile(request, username):
if request.method == "GET":
user_info = None
try:
user_info = User.objects.get(username=username)
except Error:
return render(request, "network/notfound.html")
posts = Post.objects.filter(user=user_info).reverse()
followers = Follow.objects.filter(followee=user_info).count()
follows = Follow.objects.filter(user=user_info).count()
is_following = True
try:
Follow.objects.get(user=request.user, followee=user_info)
except Follow.DoesNotExist:
is_following = False
liked_posts = Like.objects.filter(user=user_info)
print(liked_posts)
JsonResponse({"found": "profile has been found"}, status=200)
pages = Paginator(posts, 10)
page_num = request.GET.get('page')
page_obj = pages.get_page(page_num)
return render(request, "network/profile.html", {
"username": user_info.username,
"pages": page_obj,
"followers": followers,
"follows": follows,
"following": is_following,
"liked": liked_posts
})
我在另一个论坛上得到了这个答案。
在index.html
代码:
{% if user.is_authenticated %}
{% for like in liked %}
{% if like.liked_post == page %}
<span class="is-liked-unlike"><button class="btn btn-secondary" id="unlike">Unlike</button></span>
<span class="is-liked-like"><button class="btn btn-secondary" style="display:none"
id="like">Like</button></span>
{% endif %}
{% endfor %}
<span class="is-not-liked-likeBtn"><button class="btn btn-secondary" id="like">Like</button></span>
<span class="is-not-liked-unlikedBtn"><button class="btn btn-secondary" id="unlike"
style="display:none">Unlike</button></span>
{% endif %}
在network.js中,在divs.forEach中:
代码:
div.querySelectorAll(".is-liked-unlike").forEach((unliked) => {
unliked.nextElementSibling.nextElementSibling.remove();
unliked.nextElementSibling.nextElementSibling.remove();
});