Как сделать AJAX пост запрос в Django

Я хочу опубликовать комментарий с помощью ajax в Django.

У меня есть класс Message, связанный с классом Post, и я использую PostDetailView для отображения содержимого поста и комментариев.

Удалось показать опубликованный комментарий на консоли.

Я получаю ошибку jquery.js:9664 POST http://127.0.0.1:8000/post/39 403 (Forbidden)

это мой код

views.py

class PostDetailView(DetailView):
    model = Post
        
    def post(self,request,*args,**kwargs):
        if request.method == 'POST':
            postid = request.POST.get('postid')
            comment = request.POS.get('comment')            
            # post = Post.objects.get(pk=postid)
            user = request.user
            Message.objects.create(
                user = user,
                post_id = postid,
                body = comment
            )
            return JsonResponse({'bool':True})

html (где соответствует разделу комментариев)

{% if request.user.is_authenticated %}
  <div>
    <form method="POST" action="" id="form_area">
      {% csrf_token %}
      <input
        class="form-control mr-sm-2 comment-text"
        type="text"
        name="body"
        placeholder="Write Your message here..."
      />
      <button
        class="btn btn-outline-success my-2 my-sm-0 save-comment"
        type="submit"
        data-post="{{object.id}}"
        data-url="{% url 'post-detail' object.id %}"
      >
        Comment
      </button>
    </form>
  </div>
  {% else %}

script.js

function getCookie(name) {
  var cookieValue = null;
  if (document.cookie && document.cookie != "") {
    var cookies = document.cookie.split(";");
    for (var i = 0; i < cookies.length; i++) {
      var cookie = jQuery.trim(cookies[i]);
      if (cookie.substring(0, name.length + 1) == name + "=") {
        cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
        break;
      }
    }
  }
  return cookieValue;
}
var csrftoken = getCookie("csrftoken");

function csrfSafeMethod(method) {
  // these HTTP methods do not require CSRF protection
  return /^(GET|HEAD|OPTIONS|TRACE)$/.test(method);
}
function sameOrigin(url) {
  // test that a given url is a same-origin URL
  // url could be relative or scheme relative or absolute
  var host = document.location.host; // host + port
  var protocol = document.location.protocol;
  var sr_origin = "//" + host;
  var origin = protocol + sr_origin;
  // Allow absolute or scheme relative URLs to same origin
  return (
    url == origin ||
    url.slice(0, origin.length + 1) == origin + "/" ||
    url == sr_origin ||
    url.slice(0, sr_origin.length + 1) == sr_origin + "/" ||
    // or any other URL that isn't scheme relative or absolute i.e relative.
    !/^(\/\/|http:|https:).*/.test(url)
  );
}
$.ajaxSetup({
  //   headers: { "X-CSRFToken": getCookie("csrftoken") },
  beforeSend: function (xhr, settings) {
    if (!csrfSafeMethod(settings.type) && sameOrigin(settings.url)) {
      // Send the token to same-origin, relative URLs only.
      // Send the token only if the method warrants CSRF protection
      // Using the CSRFToken value acquired earlier

      xhr.setRequestHeader("X-CSRFToken", getCookie("csrftoken"));
      //   xhr.setRequestHeader("X-CSRFToken", csrftoken);
    }
  },
});


$(document).ready(function () {
  $(".save-comment").on("click", function (e) {
    e.preventDefault();
    let _comment = $(".comment-text").val();
    let _postid = $(this).data("post");
    let $crf_token = $('[name="csrfmiddlewaretoken"]').attr("value");
    $.ajax({
      url: $(this).data("url"),
      type: "post",
      headers: { "X-CSRFToken": $crf_token },
      data: {
        comment: _comment,
        postid: _postid,
        csrfmiddlewaretoken: "CSRF-TOKEN-VALUE",
      },
      dataType: "json",
      beforeSend: function () {
        $(".save-comment").addClass("disabled").text("saving...");
        console.log(_comment);
      },
      success: function (res) {
        $(".save-comment").removeClass("disabled").text("Submit");
      },
    });
  });
});

Весь мой код

Как я могу это исправить?

Скорее всего, это связано с токеном csrf. Похоже, что вы получаете токен двумя разными способами. Если вы скопировали код откуда-то, я бы рекомендовал упростить его и следовать рекомендуемому способу согласно docs.

Поскольку вы используете csrf в форме и предполагаете, что у вас установлено промежуточное ПО, у вас CSRF_USE_SESSIONS и CSRF_COOKIE_HTTPONLY должно быть установлено значение False. Поэтому просто передайте переменную, полученную из getcookie, в запрос headers: {'X-CSRFToken': csrftoken} и удалите let $crf_token = $('[name="csrfmiddlewaretoken"]').attr("value");, поскольку кажется, что вы используете ajaxSetup для установки заголовков с помощью getcookie, но затем вы перезаписываете их

Если у вас все еще проблемы, я бы предложил закомментировать все эти дополнительные проверки, которые вы делаете, следуйте простому примеру из документации. Затем, если они действительно нужны, начните добавлять проверки одну за другой, пока все не сломается, чтобы можно было отследить источник

Вернуться на верх