Почему мой код Jquery не работает после второй отправки формы? Django - Ajax - Jquery

У меня есть кнопка следовать/не следовать. В настоящее время мой Jquery работает при первой отправке, но когда я переключаю кнопку снова, Jquery не изменяет ни один из элементов.

html

    {% for user in followers %}
<div class="flist" id="flist-{{ user.profile.pk }}">
    <article class="media comment-section"> 
    <a class="mr-2" href="{% url 'user-posts' user %}"> 
    <img class="rounded-circle comment-img" src="{{ user.profile.image.url }}"></a>
        <div class="media-body mt-1">

        {% if user.profile in following %}
        <div class="remove-follower-div-{{ user.profile.pk }}">
            <form method="POST" action="{% url 'remove-follower-js' user.profile.pk %}" class="remove-follower-form" id="{{ user.profile.pk }}">
            {% csrf_token %}
            <button class="btn btn-unfollow unfollow-link" type="submit" style="float:right;" id="unfollow-button-{{ user.profile.pk }}"><span>Following</span></button>
            </form>
        </div>
        {% else %}
        <div class="add-follower-div-{{ user.profile.pk }}">
            <form method="POST" action="{% url 'add-follower-js' user.profile.pk %}" class="add-follower-form" id="{{ user.profile.pk }}">
            {% csrf_token %}
            <input type="hidden" name="profile_id" value="{{ user.profile.pk }}">
            <button class="btn btn-follow btn-light side-link mr-4" type="submit" style="float:right;" id="follow-button-{{ user.profile.pk }}">Follow</button>
            </form>
        </div>
        {% endif %}

.js файл

$( document ).ready(function() {


$('.add-follower-form').on("submit", function(e) {
    e.preventDefault();
    const profile_id = $(this).attr('id');
    
    console.log(profile_id)

    const url = $(this).attr('action');
    console.log(url)

    $.ajax({
        type: 'POST',
        url: url,
        data: {
            'csrfmiddlewaretoken': $('input[name=csrfmiddlewaretoken]').val(),
            'profile_id':profile_id,
        },
        dataType: 'json',
        success: function(response) {
            console.log('success')
            console.log(response)
            console.log(profile_id)
            console.log(url)
            
            $(`.add-follower-div-${profile_id}`).find('.add-follower-form').attr('action', "/profile/"+ profile_id + "/followers/remove/js");
            $(`.add-follower-div-${profile_id}`).find('.add-follower-form').attr('class', "remove-follower-form");
            $(`.add-follower-div-${profile_id}`).attr('class', `remove-follower-div-${profile_id}`);
            $(`#follow-button-${profile_id}`).attr('class',"btn btn-unfollow unfollow-link");
            $(`#follow-button-${profile_id}`).empty();
            $(`#follow-button-${profile_id}`).append('<span>Following</span>');
            $(`#follow-button-${profile_id}`).attr('id',"unfollow-button-"+profile_id);
            
        },
        error: function(response) {
            console.log('error', response);
        }
    });
});


$('.remove-follower-form').on("submit", function(e) {
    e.preventDefault();
    const profile_id = $(this).attr('id');
    
    console.log(profile_id)

    const url = $(this).attr('action');
    console.log(url)

    $.ajax({
        type: 'POST',
        url: url,
        data: {
            'csrfmiddlewaretoken': $('input[name=csrfmiddlewaretoken]').val(),
            'profile_id':profile_id,
        },
        dataType: 'json',
        success: function(response) {
            console.log('success')
            console.log(response)
            console.log(profile_id)
            console.log(url)
            
            $(`.remove-follower-div-${profile_id}`).find('.remove-follower-form').attr('action', "/profile/"+ profile_id + "/followers/add/js");
            $(`.remove-follower-div-${profile_id}`).find('.remove-follower-form').attr('class', "add-follower-form");
            $(`.remove-follower-div-${profile_id}`).attr('class', `add-follower-div-${profile_id}`);
            $(`#unfollow-button-${profile_id}`).attr('class',"btn btn-follow btn-light side-link mr-4");
            $(`#unfollow-button-${profile_id}`).find('span').remove();
            $(`#unfollow-button-${profile_id}`).text("Follow");
            $(`#unfollow-button-${profile_id}`).attr('id',"follow-button-"+profile_id);
            
        },
        error: function(response) {
            console.log('error', response);
        }
    });
});
});

views.py

#AJAX RESPONSE FOR FOLLOWERS.HTML, FOLLOWING.HTML
def add_follower_js(request, *args, **kwargs):
if request.method == 'POST':
    pk = request.POST.get('profile_id')
    profile = Profile.objects.get(pk=pk)
    profile.followers.add(request.user)

    data = {
        'success': '1',
    }
    return JsonResponse(data, safe=False, status=200)
return redirect(request.META.get('HTTP_REFERER', 'redirect_if_referer_not_found'))

def remove_follower_js(request, *args, **kwargs):
if request.method == 'POST':
    pk = request.POST.get('profile_id')
    profile = Profile.objects.get(pk=pk)
    profile.followers.remove(request.user)

    data = {
        'success': '1',
    }
    return JsonResponse(data, safe=False, status=200)
return redirect(request.META.get('HTTP_REFERER', 'redirect_if_referer_not_found'))

urls.py

path('profile/<int:pk>/followers/add/js', user_views.add_follower_js, name='add-follower-js'),
path('profile/<int:pk>/followers/remove/js', user_views.remove_follower_js, name='remove-follower-js'),

enter image description here

Пример: Если кнопка находится в данный момент (показано Далее):

        <div class="remove-follower-div-{{ user.profile.pk }}">
        <form method="POST" action="{% url 'remove-follower-js' user.profile.pk %}" class="remove-follower-form" id="{{ user.profile.pk }}">
        {% csrf_token %}
        <button class="btn btn-unfollow unfollow-link" type="submit" style="float:right;" id="unfollow-button-{{ user.profile.pk }}"><span>Following</span></button>
        </form>
    </div>

Я нажимаю ее, кнопка отправляет форму, просмотр возвращается успешно, и html кнопки изменяется на (показывая Follow):

        <div class="add-follower-div-{{ user.profile.pk }}">
        <form method="POST" action="{% url 'add-follower-js' user.profile.pk %}" class="add-follower-form" id="{{ user.profile.pk }}">
        {% csrf_token %}
        <input type="hidden" name="profile_id" value="{{ user.profile.pk }}">
        <button class="btn btn-follow btn-light side-link mr-4" type="submit" style="float:right;" id="follow-button-{{ user.profile.pk }}">Follow</button>
        </form>
    </div>

Но когда я нажимаю на него снова, html не меняется, показывая "Следуйте". url и весь html остаются прежними. что я делаю не так...

Я потратил несколько минут, просматривая ваш код, чтобы понять, в чем может быть ошибка, но, честно говоря, я думаю, что есть принципиально лучший способ сделать это, который не будет таким повторяющимся и громоздким, с точки зрения JS. Я бы предложил иметь единый вид и url для переключения того, является ли кто-то последователем или нет. Это сделает все намного проще. Смотрите ниже:

# template - a single form, the if-statement controls the text only
<form method="POST" 
    class="follower-form" 
    action="{% url 'toggle-following' user.profile.pk %}">
    {% csrf_token %}
    <button class="btn" type="submit" style="float:right;">
        {% if user.profile in following %}
        Following
        {% else %}
        Follow
        {% endif %}
    </button>
</form>

Затем мы позволим представлению сделать подъем, обратите внимание на изменение имени. Я также изменил URL, но я уверен, что вы знаете, как это изменить. У нас есть простой if-выражение, которое проверяет, следит ли кто-то за нами или нет, устанавливает соответствующее действие и определяет ответ. Я изменил JSON-ответ на простой HTTP-ответ, потому что JSON здесь не нужен:

def toggle_follower(request, pk):
    if request.method != 'POST':
        return redirect(... # truncated

    profile = Profile.objects.get(pk=pk)

    if request.user not in profile_followers.all():
        profile.followers.add(request.user)
        return HttpResponse("Following") # JSON response is unnecessary
    else:
        profile.followers.remove(request.user)
        return HttpResponse("Follow")

Поскольку мы определяем значение на сервере и у нас есть только одна форма, которая обрабатывает обе функции follow/unfollow, ваш Jquery становится намного более лаконичным:

$('.follower-form').on("submit", function(e) {
    e.preventDefault();
    const url = $(this).attr('action');

    $.ajax({
        type: 'POST',
        url: url,
        data: {
            'csrfmiddlewaretoken': ... // truncated
        },
        success: function(response) {
          // simply set the button text to the response
          e.target.innerText = response
        },
        ...
    });
});
Вернуться на верх