Ajax запрос работает только для одного элемента в шаблоне Django
У меня есть видео на сайте (на Django). Каждое видео, находится в модальном окне и под видео есть возможность добавить комментарии. Я сделал добавление комментариев с помощью Ajax и все работает нормально, но только для первого видео. Когда я, пытаюсь добавить комментарий на следующие видео, Django мне выдаёт ошибку:
Internal Server Error: /
Traceback (most recent call last):
File "/home/ziotyr/PycharmProjects/HROTIAS/venv/lib/python3.8/site-packages/django/core/handlers/exception.py", line 34, in inner
response = get_response(request)
File "/home/ziotyr/PycharmProjects/HROTIAS/venv/lib/python3.8/site-packages/django/core/handlers/base.py", line 124, in _get_response
raise ValueError(
ValueError: The view videoHosting.views.index didn't return an HttpResponse object. It returned None instead.
[28/Feb/2020 21:52:42] "POST / HTTP/1.1" 500 63259
Пишет, что мои представления возвращают None, а не HttpResponse, но почему-то для первого видео всё отрабатывает нормально.
Вот сам код views.py:
from django.shortcuts import render
from django.http import JsonResponse
from .models import Xvideo, Comment
# Create your views here.
def index(request):
if request.method == 'POST' and request.is_ajax():
response_data = {}
comment_under_the_video = Comment(
user=request.user,
video=Xvideo.objects.get(pk=request.POST.get('video')),
content_text=request.POST.get('comment')
)
comment_under_the_video.save()
response_data['result'] = 'Create post successful!'
response_data['user'] = comment_under_the_video.user.username
response_data['comment'] = comment_under_the_video.content_text
response_data['date'] = comment_under_the_video.pub_date
return JsonResponse(response_data)
if request.method == "GET":
file_list = Xvideo.objects.all()
context = {'videos': file_list}
return render(request, 'videoHosting/index.html', context)
Вот код с Ajax запросом:
// Отправка и добавление комментариев
$('#commentForm').on('submit', function (e) {
e.preventDefault();
function getCookie(name) {
let cookieValue = null;
if (document.cookie && document.cookie !== '') {
let cookies = document.cookie.split(';');
for (let i = 0; i < cookies.length; i++) {
let cookie = jQuery.trim(cookies[i]);
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
let csrftoken = getCookie('csrftoken');
console.log("create post is working!");
$.ajax({
url: "/",
type: "POST",
data: {
comment: $('#id_content_text').val(),
video: $('#video').val(),
csrfmiddlewaretoken: getCookie('csrftoken'),
},
success: function (json) {
$('#id_content_text').val('');
$("#talk").prepend("<li><strong>" + json.comment + "</strong> - <em> " + json.user + "</em> - <span> " + json.date + "</span></li>");
console.log("success");
},
error: function (xhr, errmsg, err) {
console.log(`Error ` + xhr + ' ' + errmsg + ' ' + err)
}
});
});
А вот код HTML шаблона:
{% load static %}
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Главная</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"
integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<link rel="stylesheet" href="{% static 'videoHosting/css/style.css' %}">
</head>
<body>
<div class="wrapper">
<header class="container-fluid bg-dark">
<nav class="navbar navbar-expand-lg navbar-dark row">
<div class="col-1">
<a href="{% url 'videoHosting:index' %}">
<svg class="bi bi-camera-video text-white-50" width="50px" height="50px" viewBox="0 0 20 20"
fill="currentColor"
xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd"
d="M4.667 5.5c-.645 0-1.167.522-1.167 1.167v6.666c0 .645.522 1.167 1.167 1.167h6.666c.645 0 1.167-.522 1.167-1.167V6.667c0-.645-.522-1.167-1.167-1.167H4.667zM2.5 6.667C2.5 5.47 3.47 4.5 4.667 4.5h6.666c1.197 0 2.167.97 2.167 2.167v6.666c0 1.197-.97 2.167-2.167 2.167H4.667A2.167 2.167 0 012.5 13.333V6.667z"
clip-rule="evenodd"></path>
<path fill-rule="evenodd"
d="M13.25 7.65l2.768-1.605a.318.318 0 01.482.263v7.384c0 .228-.26.393-.482.264l-2.767-1.605-.502.865 2.767 1.605c.859.498 1.984-.095 1.984-1.129V6.308c0-1.033-1.125-1.626-1.984-1.128L12.75 6.785l.502.865z"
clip-rule="evenodd"></path>
</svg>
</a>
</div>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedCountent"
aria-controls="navbarSupportedCountent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse justify-content-end" id="navbarSupportedCountent">
<ul class="navbar-nav">
{% if request.user.is_authenticated %}
<li class="nav-item active linki">
<a href="{% url 'account_logout' %}"
class="nav-link text-center btn btn-dark a-nav">Выход</a>
</li>
{% else %}
<li class="nav-item active linki">
<a href="{% url 'account_signup' %}" class="nav-link text-center btn btn-dark a-nav">Регистрация</a>
</li>
<li class="nav-item active">
<a href="{% url 'account_login' %}"
class="nav-link text-center btn btn-dark a-nav2">Вход</a>
</li>
{% endif %}
</ul>
<form class="form-inline my-2 my-lg-0 search">
<input type="text" class="form-control mr-sm-2 btn-input" placeholder="Поиск" aria-label="Search">
<button class="btn btn-outline-success my-2 my-sm-0 btn-search">Найти</button>
</form>
</div>
</nav>
</header>
<main class="container">
<div class="main-content my-4">
<div class="row">
{% for video in videos %}
<!-- Button trigger modal -->
<div class="col-md-4">
<div class="card mb-4 box-shadow modal_cursor" data-target="#exampleModal-{{ forloop.counter }}"
data-toggle="modal">
<span class="text-center">{{ video.name }}</span>
<img class="card-img-top"
data-src="holder.js/100px225?theme=thumb&bg=55595c&fg=eceeef&text=Thumbnail"
alt="Thumbnail [100%x225]" style="height: 225px; width: 100%; display: block;"
src="{{ video.video_splash_screen.url }}"
data-holder-rendered="true">
<div class="card-body">
<div class="row d-flex justify-content-between align-items-center">
<div class="btn-group col-5">
<button type="button" class="btn btn-primary" data-toggle="modal"
data-target="#exampleModal">
Открыть
</button>
</div>
<small class="text-muted">{{ video.pub_date }}</small>
</div>
</div>
</div>
</div>
<!-- Modal -->
<div class="modal fade" id="exampleModal-{{ forloop.counter }}" tabindex="-1" role="dialog"
aria-labelledby="exampleModalLabel"
aria-hidden="true">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">{{ video.name }}</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div class="video">
<video class="video_elem col-sm" controls name="media">
<source src="{{ video.file.url }}" type="video/mp4">
</video>
</div>
</div>
<div class="modal-footer">
<div class="container">
<div class="row justify-content-between">
<button class="btn btn-primary" type="button" data-toggle="collapse"
data-target="#multiCollapseExample1" aria-expanded="false"
aria-controls="multiCollapseExample1">
Описание
</button>
<div>
<button class="btn btn-primary" type="button" data-toggle="collapse"
data-target="#multiCollapseExample2" aria-expanded="false"
aria-controls="multiCollapseExample2">
Комментарии
</button>
</div>
</div>
<div>
{# DESCRIPTION VIDEO #}
<div class="mt-2">
<div class="collapse multi-collapse" id="multiCollapseExample1">
<div class="card card-body">
{{ video.description }}
</div>
</div>
</div>
{# COMMENTS #}
<div class="mt-2">
<div class="collapse multi-collapse" id="multiCollapseExample2">
<div class="card card-body">
<div class="body_comment">
{% if request.user.is_authenticated %}
<form method="POST" class="commentForm"
id="commentForm">
{% csrf_token %}
<input id="video" type="hidden" name="video"
value="{{ video.id }}">
<p>
<label for="id_content_text">Комментарий:</label>
<textarea name="content_text" cols="40"
rows="10"
maxlength="1000" required=""
id="id_content_text"></textarea>
</p>
<input type="submit">
</form>
{% else %}
<p>Хочешь коментить, зарегайся на сайте</p>
{% endif %}
</div>
<div class="footer_comment">
{% for comment in video.comment_set.all reversed %}
<ul id="talk">
<li>{{ comment.content_text }}</li>
</ul>
{% endfor %}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
</main>
<footer class="footer mt-auto py-3 justify-content-end navbar-fixed-bottom">
<div class="container">
<span class="text-muted">Place sticky footer content here.</span>
</div>
</footer>
</div>
<script src="https://vjs.zencdn.net/7.6.6/video.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/popper.min.js"
integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo"
crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"
integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6"
crossorigin="anonymous"></script>
<script src="{% static 'videoHosting/js/script.js' %}"></script>
</body>
</html>
Ответы (1 шт):
Автор решения: Igor
→ Ссылка
Не используйте на странице повторяющиеся id.
$('.commentForm').on('submit', function (e) {
...
var $form = $(this);
$.ajax({
url: "/",
type: "POST",
data: {
comment: $form.find('.content_text').val(),
video: $form.find('.video').val(),
csrfmiddlewaretoken: getCookie('csrftoken')
},
success: function (json) {
$form.find('.content_text').val('');
...
<form method="POST" class="commentForm">
{% csrf_token %}
<input class="video" type="hidden" name="video" value="{{ video.id }}">
<p>
<label>Комментарий:<br/>
<textarea name="content_text" cols="40" rows="10" maxlength="1000" required=""
class="content_text"></textarea>
</label>
</p>
<input type="submit">
</form>