Получение идентификатора экземпляра объекта из request.POST при использовании javascript e.preventDefault () - PullRequest
0 голосов
/ 30 марта 2020

Я использую модальный bootstrap для вывода списка экземпляров объектов и выполнения операций CRUD. Я обернул весь список в форму и передал идентификатор каждого отдельного экземпляра объекта в представление, используя имена и значения кнопок, чтобы манипулировать (CRUD) одним экземпляром объекта за раз. Когда я удаляю объект без использования Javascript, представление работает нормально, но как только я добавляю строку e.preventDefault();, идентификатор выбранного объекта больше не фиксируется в запросе.

почему что?

Более детально шаблон выглядит так:

<form
action="{% url 'delete_habit' %}"
method="POST"
id="deleteForm">{% csrf_token %}
 <div class="row">
  <div class="col-12 pb-3">
   <table class="modal-table border" id="habitsTable">
    <tbody>
      {% for habit in habits %}
       <tr class="border js-row-{{habit.id}}">
        <td class="border">
          <img src="{% static 'img/bars_icon.svg' %}">
        </td>
        <td class="text-left border px-3">{{habit.name}}</td>
        <td class="border">
          <button
           id="delete-{{habit.id}}"
           type="submit"
           value="{{habit.id}}"
           name="habit_id"
           class="btn">
               <img src="{% static 'img/minus_icon.svg' %}">
          </button>
         </td>
       </tr>
       {% endfor %}
     </tbody>
    </table>
   </div>
 </div>
</form>

Вид:

def delete_habit(request):
    habit_id = request.POST.get('habit_id') --> this fails when e.preventDefault()
    data = {'habit_deleted': int(habit_id)}
    habit_to_delete = Habit.objects.filter(id=int(habit_id)).filter(
        user=request.user)
    habit_to_delete.delete()
    return JsonResponse(data)

javascript:

var deleteForm = document.getElementById('deleteForm');
if (deleteForm  !== null){
  deleteForm.addEventListener('submit', function(e){
      var formData = new FormData(deleteForm);
      e.preventDefault();
      var request = new XMLHttpRequest();
      request.open(deleteForm.method, deleteForm.action, true);
      var cookies = parse_cookies();
      request.setRequestHeader('X-CSRFToken', cookies['csrftoken']);
      request.onload = function() {
        if (this.status >= 200 && this.status < 400) {
          var data = JSON.parse(this.response);
          removeRow("js-row-" + data.habit_deleted);
        };
      };
      request.send(formData);
  });
};

Строка e.preventDefault() кажется виновной, так как, когда я добавляю эту строку в JS, запрос не возвращает идентификатор выбранной привычки.

Ответы [ 2 ]

0 голосов
/ 01 апреля 2020

С помощью @GrandPhuba и очень мудрого друга я изменил поведение таблицы для использования якорей:

Таблица:

<table class="modal-table border" id="habitsTable">
  <tbody>
  {% for habit in habits %}
    <tr class="habit-{{habit.id}}">
      <td class="text-left border px-3">{{habit.name}}</td>
      <td>
        <a class="delete-link"
        href="{% url 'delete_habit' habit.id %}"
        data-habit="{{habit.id}}" onkeyup="">
          <img src="{% static 'img/minus_icon.svg' %}">
        </a>
      </td>
    </tr>
  {% endfor %}
  </tbody>
</table>

javascript:

var anchors = document.getElementsByClassName("delete-link");

  var removeHabit = function(e) {
    e.preventDefault();
    var habit_id = this.getAttribute("data-habit");
    var request = new XMLHttpRequest();
    request.open("POST", this.href, true);
    var cookies = parse_cookies();
    request.setRequestHeader('X-CSRFToken', cookies['csrftoken']);
    request.setRequestHeader('Content-Type', 'application/json');
    request.send(JSON.stringify({
        habit_id: habit_id
    }));
    removeRow("habit-"+ habit_id);
  };

  for (var i = 0; i < anchors.length; i++) {
    anchors[i].addEventListener('click', removeHabit, false);
  }

вид:

def delete_habit(request, habit_id):
    habit_to_delete = Habit.objects.get(pk=habit_id)
    habit_to_delete.delete()
    return HttpResponseRedirect(reverse('home'))
0 голосов
/ 30 марта 2020

Давайте исправим проблемы одну за другой:

Проблема 1: Пустые данные

Почему-то я думаю, что new FormData(deleteForm) приводит к пустому объекту, поэтому попробуйте сериализовать форму вручную

function formToJson(formElement){
    var inputElements = formElement.getElementsByTagName("input"),
        jsonObject = {};
    for(var i = 0; i < inputElements.length; i++){
        var inputElement = inputElements[i];
        jsonObject[inputElement.name] = inputElement.value;

    }
    return JSON.stringify(jsonObject);
}

Затем в вашем HTML измените следующее с:

<td class="border">
    <button id="delete-{{habit.id}}" type="submit" value="{{habit.id}}" name="habit_id" class="btn">
        <img src="{% static 'img/minus_icon.svg' %}">
    </button>
</td>

На:

<td class="border">
    <input type="hidden" value="{{habit.id}}" name="habit_id">
    <button id="delete-{{habit.id}}" type="submit" class="btn">
        <img src="{% static 'img/minus_icon.svg' %}">
    </button>
</td>

Затем в слушателе:

request.send(JSON.stringify(formToJson(deleteForm)))

Проблема 2: Неверный метод HTTP

Параметр method для XMLHttpRequest.open() чувствителен к регистру (должен быть прописными), а deleteForm.method - в нижнем регистре.

Попробуйте вместо этого:

request.open(deleteForm.method.toUpperCase(), deleteForm.action, true);

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...