Введение: Я создаю приложение вопросов и ответов в стиле stackoverflow, где пользователь может задать вопрос, а другие пользователи могут ответить на вопрос.Пользователи также имеют возможность Upvote и Downvote как вопросы, так и ответы.Я использую Ajax-вызовы для асинхронного обновления upvote и downvote.
Я был успешен в асинхронном повышении и понижении вопросов.но почему-то тот же код дает мне статус Метод не разрешен 405 в ответе upvote / downvote ( См. изображения ниже )
для удобства и сохранениямаленький код позволяет говорить только об ответе upvote code
![enter image description here](https://i.stack.imgur.com/iSvz0.png)
Я полагаю, что могуя делаю что-то неправильно в URL или в вызывающей функции URL в модели
Models.py
class Answer(models.Model):
question = models.ForeignKey(Question, related_name='answers')
author = models.ForeignKey(User, related_name='answers')
text = models.TextField()
ansup = models.ManyToManyField(User, blank=True, related_name='answer_ansup')
ansdown = models.ManyToManyField(User, blank=True, related_name='answer_ansdown')
def get_absolute_url(self):
return reverse('questions:single', kwargs={'username': self.question.user.username,
'slug': self.question.slug})
def get_ansup_url(self): #This is the 1 of 2 place I believe I may be doing something wrong
return reverse('questions:ansup', kwargs={'username': self.author.username,
'pk': self.pk})
def get_ansdown_url(self):
return reverse('questions:ansdown', kwargs={'username': self.author.username,
'pk': self.pk})
Ниже приведены виды.py
class AnswerAnsupToggle(LoginRequiredMixin, RedirectView):
def post(self, *args, **kwargs):
pk = self.kwargs.get('pk')
obj = get_object_or_404(Answer, pk=pk)
user = self.request.user
context = {"answer": obj}
if user in obj.ansup.all():
obj.ansup.remove(user)
else:
obj.ansup.add(user)
if self.request.is_ajax():
html = render_to_string("questions/answer_upvote_section.html", context, request=self.request)
return JsonResponse({"form": html})
url = obj.get_absolute_url()
print(url)
return HttpResponseRedirect(url)
Ниже приведены шаблоны
Обратите внимание, что шаблоны для модели ответа немного сложны.Каждый вопрос находится на отдельной странице. (Detail DetailView) Однако все ответы на этот вопрос также находятся на одной странице.Ответы не имеют подробного представления. Переменная answer
происходит из forloop, как вы можете видеть ниже.Помещение скрипта в forloop портит код очень плохо.Это означает, что вы нажимаете upvote, когда он запускается несколько раз.Плюс это даже не соответствует тому же самому ответу время от времени.
{% for answer in question.answers.all %}
{% if user in answer.ansup.all %}
<form action="{% url 'questions:ansup' username=answer.author.username pk=answer.pk %}" method="post" >
{% csrf_token %}
<button type="submit" style="margin-left:-13px;" name="answer_pk" value="{{ answer.pk }}"
class="btn btn-link ans_upvote_button">
<img src="{% static 'images/Upvote.png' %}" height="25px">
</button>
</form>
{% else %}
<form action="{% url 'questions:ansup' username=answer.author.username pk=answer.pk %}" method="post" >
{% csrf_token %}
<button type="submit" style="margin-left:-13px;" name="answer_pk" value="{{ answer.pk }}"
class="btn btn-link ans_upvote_button">
<img src="{% static 'images/Upvote_blank.png' %}" height="25px">
</button>
</form>
{% endif %}
Ниже приведены urls.py Это на 2-х местах, я сомневаюсь, что могу что-то делать не так
Детальный вид страницы вопросов / ответов
url(r'^(?P<username>[-\w]+)/(?P<slug>[-\w]+)/$', views.QuestionDetail.as_view(), name='single'),
Ответ Upvote Url
url(r'^(?P<username>[-\w]+)/(?P<pk>\d+)/ansup/$', views.AnswerAnsupToggle.as_view(), name='ansup'),
Ниже приведен JS
<script>
$(document).ready(function () {
$(document).on('click', ".ans_upvote_button", function( event ){
event.preventDefault();
var pk = $(this).attr("value");
var upvote = $("#answer_upvote_section");
$.ajax({
url : "{{answer.get_ansup_url}}",
type: "POST",
data: {
"pk": pk,
"csrfmiddlewaretoken": "{{ csrf_token }}"
},
dataType: "json",
success: function (data) {
upvote.html(data["form"]);
}, error: function (rs, e) {
console.log(rs, e);
}
});
});
});
</script>