I cannot figure out why I keep getting this "NoReverseMatch at /
". I am trying to add AJAX to a form to save posts. It seems to be a problem with the URL in the Javascript, but I cannot figure out exactly what it is. Can anyone tell me what is wrong here? Thank you in advance.
urls.py
path('', PopularPostListView.as_view(), name='popular'),
path('save/<int:pk>', views.AjaxSave, name='save-post'),
views.py
#This is the view for the save
def AjaxSave(request, pk):
if request.POST.get('action') == 'post':
id = int(request.POST.get('postid'))
result = post.saves.count()
post = get_object_or_404(Post, id=id)
if post.saves.filter(id=request.user.id).exists():
post.saves.remove(request.user)
post.save()
else:
post.saves.add(request.user)
post.save()
return JsonResponse({'result': result, })
#This is the view for the popular page
class PopularPostListView(ListView):
model = Post
template_name = 'blog/popular.html'
context_object_name = 'posts'
ordering = ['-pinned', '-date_posted']
paginate_by = 25
queryset = Post.objects.all().filter(approved=True).order_by('-date_posted', '-pinned')
popular.html
{% extends "blog/base.html" %}
{% block content %}
<h1>Popular Posts</h1>
<div style="margin-left: 10%;">
{% for post in posts %}
<article >
<img src="{{ post.author.profile.image.url }}">
<div >
<div >
<a href="{% url 'user-posts' post.author.username %}">{{ post.author }}</a>
<small >{{ post.date_posted|date:"F d, Y P" }}</small>
</div>
<h3><a href="{% url 'post-detail' post.id %}">{{ post.title }}</a></h3>
<p >{{ post.content|urlize }}</p>
<!--Display image-->
{% if post.image %}
<img style="max-width: 100%; max-height: 100%;" src="{{ post.image.url }}">
{% else %}
{{ NONE }}
{% endif %}
<!--Display video-->
{% if post.video %}
<video style="max-width: 100%; max-height: 100%;" src="{{ post.video.url }}" controls></video>
{% endif %}
<hr>
<!--Dropdown for post options-->
<div >
<button ><i ></i></button>
<div >
<div>
<!--Displaying save form-->
<form action="{% url 'save-post' post.id %}" id="save" method="post">
{% csrf_token %}
<button type="submit" name="post_id" title="Save Post" id="save" value="{{ post.id }}">
<i ></i> Save Post
</button>
</form>
</div>
<div>
<!--Displaying report button-->
<form action="{% url 'report_post' post.id %}" method="post">
{% csrf_token %}
{% if user != post.author %}
<button type="submit" name="post_id" title="Report Post" value="{{ post.id }}" onclick="reportThank();">
<i ></i> Report Post
</button>
{% endif %}
</form>
</div>
</div>
</div>
<div>
<!--Showing report count to staff-->
{% if user.is_staff %}
<small style="margin-left: 0%;">Reports:</small> {{ post.total_reports }}
{% endif %}
</div>
</article>
{% endfor %}
</div>
<!--Ajax script to stop page refresh on save form submission-->
<script>
$(document).on('click', '#save', function (e){
e.preventDefault();
$.ajax({
type: 'POST',
url: "{% url 'popular' %}",
data: {
postid: $('#save').val(),
csrfmiddlewaretoken: $('input[name=csrfmiddlewaretoken]').val(),
action: 'post'
},
success: function (json) {
alert('Post saved!')
},
error: function () {
alert('Error!')
}
});
})
</script>
Javascript
<script>
$(document).on('click', '#save', function (e){
e.preventDefault();
$.ajax({
type: 'POST',
url: "{% url 'save-post' post.id %}",
data: {
postid: $('#save').val(),
csrfmiddlewaretoken: $('input[name=csrfmiddlewaretoken]').val(),
action: 'post'
},
success: function (json) {
alert('Post saved!')
},
error: function () {
alert('Error!')
}
});
})
</script>
CodePudding user response:
in the Ajaxsave function you didnt specifiy the pk you should link it to one of the objects then start making the post so the view couldn't return back the reverse query you are trying to load , the best practices for using AJAX request is by using Django-Rest-Framework so it handle all the requests.
def AjaxSave(request, pk):
pk = module.objects.get(pk=pk)
if request.method == "POST":
# or you can get the pk here if you want without parsing to int
id = int(request.POST.get('postid'))
result = post.saves.count()
post = get_object_or_404(Post, id=id)
if post.saves.filter(id=request.user.id).exists():
post.saves.remove(request.user)
post.save()
else:
post.saves.add(request.user)
post.save()
return JsonResponse({'result': result, })
CodePudding user response:
Error is comming from this line url: "{% url 'save-post' post.id %}",
here you don't have access to your post
object because it's not inside loop you can solve your problem like this you don't have create form and set your button type to submit if you're using ajax request change your code like this
<button type="button" name="post_id" title="Save Post" id="save" onclick="savePost(event)" value="{{ post.id }}" data-url="{% url 'save-post' post.id %}">
<i ></i> Save Post
</button>
and you ajax call will look like this
<script>
function savePost(event){
var url = event.target.getAttribute("data-url");
$.ajax({
type: 'POST',
url: url,
data: {
postid: event.target.getAttribute('value'),
csrfmiddlewaretoken: "{{csrf_token}}",
action: 'post'
},
success: function (json) {
alert('Post saved!')
},
error: function () {
alert('Error!')
}
});
}
</script>