Django кнопка отправки не работает по запросу Ajax - PullRequest
1 голос
/ 31 марта 2020

Я создаю веб-сайт, на котором пользователи могут создавать посты и комментировать его, однако после нажатия кнопки «Отправить» в шаблоне post_detail. html для отправки комментария ничего не происходит, и я не могу увидеть ошибку. Я использую jQuery для отправки формы

это мой просмотр post_detail:

@login_required
def post_detail(request, id):
    data = dict()
    post = get_object_or_404(Post, id=id)
    if request.method == 'POST':
        form = CommentForm(request.POST)
        if form.is_valid():
            comment = form.save(False)
            comment.post = post
            comment.name = request.user
            comment.save()
            comments = post.comments.all()
            data['form_is_valid'] = True
            data['comments'] = render_to_string('home/posts/post_detail.html', { 'comments':comments }, request=request)
        else:
            data['form_is_valid'] = False
    else: 
        form = CommentForm
        comments = post.comments.all()
    context  = {
        'form': form,
        'comments': comments,
        'post': post
    }
    data['html_data'] = render_to_string('home/posts/post_detail.html', context,request=request)
    return JsonResponse(data)

это мой post_detail. html шаблон:

       {% load crispy_forms_tags %}
        {% load static %}
        <script src="{% static 'js/comment.js' %}"></script>
        <div class="modal-header-sm">
          <button type="button" class="close mx-2" data-dismiss="modal" aria-label="Close">
            <span aria-hidden="true">&times;</span>
          </button>
        </div>
        <div class="card  mt-3 rounded-0 mb-3" style="max-width: 100rem !important;">
            <div class="card-body text-dark">
              <div class="d-flex">
                <img class="img-create-post rounded-circle mr-2" style="width: 50px;height: 50px;" src="https://mdbootstrap.com/img/Photos/Avatars/avatar-5.jpg"
                  alt="Profile image">
                  <span class="align-text-top"><a class="mr-2 text-dark font-weight-bolder" href="#">{{ post.author.first_name }} {{ post.author.last_name }} </a><br><p class="font-weight-light text-muted">{{ post.title }}</p></span>
                    <div class="float-right text-right ml-auto">
                      <p class="text-muted small" style="font-size: 0.7rem;">{{ post.date_posted|date:"F d, Y" }}</p>
                    </div>     
              </div>
              <p class="card-text">{{ post.content }}</p>
            </div>
            <div class="card-footer" style="height: 5rem;">
              <a class="mx-1 small" data-href='{{ post.get_api_like_url }}' data-likes='{{ post.likes.count }}' href='{{ post.get_like_url }}'><i class="fas fa-thumbs-up"></i> Like</a>
              <hr class="my-1">
                <p class="text-muted small">
                  {% if post.author == request.user %}  
                  <button class="btn btn-sm text-muted show-form-delete ml-auto" data-url="{% url 'home:post-delete' post.id %}" style="font-size: small;" style="height: 0rem;">Remove</button> 
                  {% endif %}
                  <small class="float-sm-right">
                    {{ post.likes.count }} Likes, {{ post.comments.count }} Comments
                  </small>
                </p>
            </div>
            <div class="card-body">
              <div class="row">
                  <img class="img-create-post rounded-circle mr-2" style="width: 40px;height: 40px;" src="{{ request.user.image }}" alt="Profile image">


<form method="POST" data-url="{% url 'home:post-detail' post.id %}" class="post-comment-form">
        {% csrf_token %}
          <div class="row ml-1">
          {{ form | crispy }}
          <button class="btn btn-sm ml-1 small btn-rounded btn-primary" style="height: 2.3rem;" type="submit">Add</button> 
        </div>  
      </form> 
              </div>
              <hr>
          </div>
          <div id="post-linked-comments">
            <div>
              {% include 'home/posts/post_comment.html' %}
            </div>    
          </div>
          </div>

шаблон post_comment. html для вашей справки, однако, скорее всего, это не проблема:

<ul class="list-group list-group-flush">
    {% for comment in comments %}
    <li class="list-group-item">
        <div class="d-flex">
            <img class="img-create-post rounded-circle mr-1" style="width: 20px;height: 20px;" src="{{ comment.name.image }}"
              alt="Profile image">
              <span class="align-text-top font-weight-bolder">{{ comment.name.first_name }}
                <p class="text-muted small mx-2" style="font-size: 0.7rem;">{{ comment.created_on|date:"F d, Y at: f A" }}</p><br>
                <p class="font-weight-light">{{ comment.body }}</p></span> 
          </div>
    </li>
    {% empty %}
    <li class="list-group-item">
      <div class="d-flex">
              <p class="font-weight-lighter text-muted">No comments to show</p>
        </div>
    </li>
    {% endfor %}
</ul>

и, наконец, мой javascript код в комментарии. js:

$(document).ready(function(){
    var ShowForm = function(e){
        e.stopImmediatePropagation();
        var btn = $(this);
        $.ajax({
            url: btn.attr("data-url"),
            type: 'get',
            dataType:'json',
            beforeSend: function(){
                $('#modal-post-detail').modal('show');
            },
            success: function(data){
                $('#modal-post-detail .modal-content').html(data.html_data);
            }
        });
    };

    var SaveForm =  function(e){
        e.stopImmediatePropagation();
        var form = $(this);
        $.ajax({
            url: form.attr('data-url'),
            data: form.serialize(),
            type: form.attr('method'),
            dataType: 'json',
            success: function(data){
                if(data.form_is_valid){
                    $('#post-linked-comments div').html(data.comments);
                    alert('Comment added')
                } else {
                    $('#modal-post-detail .modal-content').html(data.html_data)
                }
            }
        })
        return false;
    }

//adding a comment
$('.comment-post-btn').click(ShowForm);
$('.post-detail-clickable-details-view').click(ShowForm);
$('#modal-post-detail').on("submit",".post-comment-form",SaveForm)

});

Нет проблем с получением файла Javascript, так как модал post_detail всплывает нормально, однако после нажатия на кнопку добавления ничего не происходит.

Спасибо всем заранее за помощь.

РЕДАКТИРОВАТЬ: кнопка должна быть добавлена ​​внутри формы, но теперь возникает исключение NoReverseMatchException после нажатия кнопки «Добавить»:

Новая форма:

<form method="POST" data-url="{% url 'home:post-detail' post.id %}" class="post-comment-form">
        {% csrf_token %}
          <div class="row ml-1">
          {{ form | crispy }}
          <button class="btn btn-sm ml-1 small btn-rounded btn-primary" style="height: 2.3rem;" type="submit">Add</button> 
        </div>  
      </form>

urls.py:

path('post/<int:id>/', views.post_detail, name='post-detail'),

Ошибка:

django.urls.exceptions.NoReverseMatch: Reverse for 'post-detail' with arguments '('',)' not found. 1 pattern(s) tried: ['home/post/(?P<id>[0-9]+)/$']

решено: мне удалось решить проблему самостоятельно. это было от моих взглядов. Я отправлял комментарии на неправильный шаблон html. Ниже вы можете увидеть исправленный вид шаблона.

@login_required
def post_detail(request, id):
    data = dict()
    post = get_object_or_404(Post, id=id)
    if request.method == 'POST':
        form = CommentForm(request.POST)
        if form.is_valid():
            comment = form.save(False)
            comment.post = post
            comment.name = request.user
            comment.save()
            comments = post.comments.all()
            data['form_is_valid'] = True
            #data['comments'] = render_to_string('home/posts/post_detail.html', { 'comments':comments }, request=request)
            #corrected code below
            data['comments'] = render_to_string('home/posts/post_comment.html', { 'comments':comments }, request=request)       else:
            data['form_is_valid'] = False
    else: 
        form = CommentForm
        comments = post.comments.all()
    context  = {
        'form': form,
        'comments': comments,
        'post': post
    }
    data['html_data'] = render_to_string('home/posts/post_detail.html', context,request=request)
    return JsonResponse(data)

1 Ответ

1 голос
/ 31 марта 2020

Я полагаю, что ничего не происходит, поскольку кнопка отправки не определена ни в одном из тегов формы.

Из кода в post_detail.html теги button находятся вне тегов form.


  <div class="row">
      <img class="img-create-post rounded-circle mr-2" style="width: 40px;height: 40px;" src="{{ request.user.image }}" alt="Profile image">
      <form method="POST" data-url="{% url 'home:post-detail' post.id %}" class="post-comment-form">
        {% csrf_token %}
        <div class="moda-body">
          {{ form | crispy }}
        </div>
      </form>
      <button class="btn btn-sm ml-1 small btn-rounded btn-primary" style="height: 2.3rem;" type="submit">Add</button> 
  </div>

Тег кнопки должен быть помещен перед закрывающим тегом формы.


  <div class="row">
      <img class="img-create-post rounded-circle mr-2" style="width: 40px;height: 40px;" src="{{ request.user.image }}" alt="Profile image">
      <form method="POST" data-url="{% url 'home:post-detail' post.id %}" class="post-comment-form">
        {% csrf_token %}
        <div class="moda-body">
          {{ form | crispy }}
        </div>
        <button class="btn btn-sm ml-1 small btn-rounded btn-primary" style="height: 2.3rem;" type="submit">Add</button> 
      </form>
  </div>
...