Почему мой код 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'),
Пример: Если кнопка находится в данный момент (показано Далее):
<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
},
...
});
});