通过 django 模板和 JS 动态喜欢和不喜欢按钮的问题

Problems with dynamic like and dislike buttons via django templates and JS

我正在尝试为我的 cs50w 项目动态创建和使用喜欢和不喜欢的按钮,这当然应该允许用户喜欢或不喜欢 post 并将喜欢的按钮切换到不喜欢的按钮和很快。现在,令人气愤的是,类似和不同的机制本身都可以工作,但按钮却让我很不爽。

  1. 要么我删除后无法创建相反的按钮 通过 Javascript 的原始版本(我尝试使用 appendChildCreateElement,无济于事)。
  2. 或者如果 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">&laquo; 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 &raquo;</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();
});