Как я могу использовать ajax для обновления кнопок и счетчиков без перенаправления? - PullRequest
0 голосов
/ 08 января 2020

Я пытаюсь настроить функциональность «нравится / не нравится», чтобы, если пользователь просматривает видео (например), страница не обновляет sh и не теряет прогресс в видео. Я понимаю, как изменить содержимое тега <div>, но понятия не имею, как обращаться с логи c, которые мне нужно будет использовать для изменения текста / URL-адреса кнопки (пример: если они нажимают «нравится», то «лайк» должен стать «непохожим», а URL-адрес, связанный с «лайком», должен быть изменен) Логи c в шаблон замены и удалил то, что у меня было раньше, так что прости меня за то, что я не выставил HTML.

handle_likes. js

(...)
// Handle button clicks
$(".like-btn").on('click', function(){
    console.log("Like button was clicked!"); // sanity check

    // Get the value of the original button
    if ($(".like-btn").val() == "not-liked") { 
        like_post();

    // I figured I could change the value to change the linked url
    }
    if ($(".like-btn").val() == "is-liked") {
        unlike_post();

    }

});
// Functions to handle likes/dislikes
function like_post(){
    console.log("Like post called...") // sanity check
    $.ajax({
        url: "posting/liking_post/",
        data: {
            post_id : $("#post_id").val(), // Need this to get the post
            post_type : $("#post_type").val() // This too
        },
        success: function(data) {
            $('.like-count').html(data); //Try to update the count of the likes on post
            $('.like-btn').html(data); // Try to change the like button
            },

        // Show error | display in console
        error : function(xhr,errmsg,err) {
            $('#results').html("<div class='alert-box alert radius' data-alert>Please contact an admin; We have encountered an error: "+errmsg+
                " <a href='#' class='close'>&times;</a></div>"); // add the error to the dom
            console.log(xhr.status + ": " + xhr.responseText); // provide a bit more info about the error to the console
        }
    });
};
(...)

views.py

@login_required
def like_post(request):
    """
    Checks if user already liked a post, if not then it will make a like object and assign it to the user and post
    """
    print(request.is_ajax())
    if request.is_ajax():
        post_type = request.GET.get('post_type')
        post_id = request.GET.get('post_id')

        if post_type and post_id:
            post = toolz.get_post(int(post_id), post_type)
        else:
            raise Exception("Post info not passed") # If like button clicked twice, no info is passed
        try:
            likes = list(Like.objects.filter(object_id=post_id))

            if len(likes) > 0:
                print("\n\n", likes, "\n\n") # debug
                users = list()
                for i in likes:
                    users.append(i.user)    

            if request.user in users:
                print("User has liked this post")
                return HttpResponse("Trying to like post twice...is a no no") # just a debug for myself

            else:
                like = Like(
                user=request.user,
                content_object=post
                )
                like.save()
                toolz.get_post(post_id, post_type, editing=True).update(like_count=F('like_count') + 1)
                like_count = post.like_count
                print("DEBUG 456 in like_post; user like list:", likes)
                user_liked = True
                return render(None, 'like_count.html' ,{'like_count': like_count, 'user_liked': user_liked})

        except Exception as e:
            print("\nSilent Exception; Error:", e)

    else:
        raise Exception("Request is not AJAX")

1 Ответ

0 голосов
/ 08 января 2020

Я понял это. Я добавил два метода в классы записей, которые проверяли модели «нравится» и «не нравилось» для объекта, который должен «понравиться», и возвращали пользователей, связанных с ним, в виде списка. (метод ниже) Я попытался использовать self.likes.filter(object_id=self.id), потому что у меня есть поле ManyToMany для лайков (Должен ли я заменить это на GenericRelation?), но по какой-то причине это не сработало, поэтому я просто обратился к модели напрямую. Теперь я могу обрабатывать все через ajax на той же странице в том же файле JavaScript. Logi c, если пользователь обходит шаблон logi c (пытаясь понравиться или не понравиться более одного раза ... даже если он получит исключение UNIQUE constraint failed .... Нужна ли мне даже логика c для этого?) в поле зрения.

Будучи настолько новым для JavaScript, это большая победа для меня: D

Метод класса

    def get_liked_users(self):
        all_likes = Like.objects.filter(object_id=self.id)
        users = list()
        for like in all_likes:
            users.append(like.user)
        return users

Тогда внутри шаблонов я сделал это ...

<!--Like stuff-->
{% if request.user not in post.get_liked_users %}
        <button class="like-post-btn" value="not-liked">Like</button>
{% else %}
        <button class="like-post-btn" value="is-liked">Unlike</button>
{% endif %}
        <div class="like-count">{{post.like_count}}<div>

<!--Dislike stuff-->
{% if request.user not in post.get_disliked_users %}
        <button class="dislike-post-btn" value="not-disliked">Dislike</button>
{% else %}
         <button class="dislike-post-btn" value="is-disliked">Undislike</button>
{% endif %}
        <div class="dislike-count">{{post.dislike_count}}</div>
...