Как я могу позволить пользователю редактировать комментарии в Django Blog, используя DetailView и UpdateView на одной странице?

Я занимался этим пару дней и следовал нескольким различным руководствам, чтобы получить то, что я хочу. Я довольно близок к цели. Я просто не могу понять, как сделать так, чтобы пользователь мог редактировать свой комментарий. Я пробовал несколько разных подходов... Вот что у меня получилось на данный момент...

Мои модели...

class Suggestion(models.Model):
    id = models.UUIDField(default=uuid.uuid4,primary_key=True,unique=True)
    created_by = models.ForeignKey(User,null=True,on_delete=models.DO_NOTHING,related_name='suggestion_created_by')
    last_update = models.DateTimeField(editable=False,null=True)
    suggestion_creation_date = models.DateTimeField(editable=False,null=True)
    suggestion_name = models.CharField(max_length=255,null=True)
    suggestion_status = HTMLField(blank=True,null=True)
    suggestion = HTMLField(blank=True,null=True)
    unique_identifier = models.CharField(max_length=64,null=True,blank=True)

   class Meta:
        ordering = ["suggestion_name"]
    
    def __str__(self):
        return self.suggestion_name
    
    def get_absolute_url(self):
        return reverse("Suggestions:suggestion_detail",kwargs={'pk':self.pk})

class SuggestionComment(models.Model):
    author = models.ForeignKey(User,on_delete=models.CASCADE)
    comment = models.CharField(max_length=255,blank=True)
    created_on = models.DateTimeField(default=timezone.now)
    suggestion = models.ForeignKey('Suggestion',on_delete=models.CASCADE,related_name='suggestion_comments')
    upvotes = models.ManyToManyField(User,blank=True,related_name='suggestion_comment_upvotes')

    def get_absolute_url(self):
        return reverse("Suggestions:suggestion-detail", kwargs={"pk": self.suggestion.pk})

Мои шаблоны...

DetailView...

<!DOCTYPE html>
{% extends "base21.html" %}
<title>{% block title %} LevelSet Suggestion By Name Detail {% endblock %}</title>
{% block body_block %}

<div class="box12">

  <h1 class="title">{{ suggestion_detail.suggestion_name }}</h1>

  <div class="spacer281">
    {{ suggestion_detail.suggestion|safe }}
  </div>

  {% if suggestion_detail.suggestion_status != None %}

    <div class="spacer280">
        <h2>Status - </h2>
    </div>

    <div class="spacer76">
      {{ suggestion_detail.suggestion_status|safe }}
    </div>

  {% endif %}

  <div class="spacer285">
    {% include 'suggestion_comments.html' %}
  </div>

</div>

</div>

{% endblock %}

suggestion_comments.html ( Include )

    <form method='POST' class="comment-form">
      {% csrf_token %}
        <div class="spacer284">
          {{ form.comment }}
        </div>
      <button class="button7" type="submit">Submit</button>
    </form>
    <div class="spacer286">
      {% if suggestion_comments %}
        <h2>Comments</h2>
        {% for comment in object.suggestion_comments.all %}
          <div class="spacer291">
            <p><a href="{% url 'Main:associate_directory_associate_detail' pk=comment.author.id %}">{{ comment.author }}</a> {{ comment.created_on }}</p>
            <p class="spacer290">{{ comment.comment }}</p>
              <div class="spacer289">
                <div class="upvote-comment-count">{{ comment.total_comment_upvotes }}</div>
                <button type="button" class="button6" data-href="{% url 'Suggestions:suggestion_comment_like' comment.id %}">Like</button>
                <button type="button" class="button2" data-href="">Reply</button>
                {% if comment.author == request.user %}
                  <button type="button" class="button4" id="{{ comment.id }}" pk="{{ object.pk }}" href="{% url 'Suggestions:suggestion_comment_edit' comment.id %}">Edit</button>
                  <div class="spacer159" id="hide_payment" style="display:none;">
                    <form method='POST'>
                      {% csrf_token %}
                        <div class="spacer284">
                          {{ form.comment }}
                        </div>
                      <button class="button7" type="submit">Submit</button>
                    <form>
                  </div>
                    <button type="button" class="button3" data-href="{% url 'Suggestions:suggestion_delete' comment.id %}">Delete</button>  
                {% endif %}
              </div>
            </div>
        {% endfor %}
      {% else %}
        <h2>No Comments Yet</h2>
      {% endif %}
    </div>

Мои взгляды...

class SuggestionDetailView(LoginRequiredMixin,DetailView):
    model = Suggestion
    context_object_name = 'suggestion_detail'
    template_name = 'suggestion_detail.html'

def get_context_data(self, **kwargs):
    context = super(SuggestionDetailView, self).get_context_data(**kwargs)
    form = SuggestionCommentForm()
    suggestion_comments = SuggestionComment.objects.filter(suggestion_id=self.object.pk).order_by('-created_on').all()
    context['form'] = form
    context['suggestion_comments'] = suggestion_comments
    return context

def post(self, request, *args, **kwargs):
    form = SuggestionCommentForm(request.POST)

    if form.is_valid():
        new_comment = form.save(commit=False)
        new_comment.author = request.user
        new_comment.suggestion = self.get_object()
        new_comment.save()
        self.object = self.get_object()
        context = self.get_context_data(object=self.object)
        html = render_to_string('suggestion_comments.html', context, request=self.request)
        return JsonResponse({'form': html})

    else:

        form_errors = form.errors.as_json()
        response = HttpResponse(form_errors, status=400)
        response['content_type'] = 'application/json'
        return response
  • Ниже я использую представление на основе функций, поскольку я не смог понять, как заставить работать UpdateView, и нашел в Интернете пример представления на основе функций.....

    .
    def suggestion_comment_edit_view(request, id):
         comment = get_object_or_404(SuggestionComment, pk=id) 
    
         if request.method == "POST":
             form = SuggestionEditCommentForm(request.POST, instance=comment)
    
             if form.is_valid():
                comment = form.save(commit=False)
                comment.save()
                return
          else:
             form = SuggestionEditCommentForm(instance=comment)
    
          return render(request, 'suggestion_comments.html', {'form': form})
    

А вот немного AJAX...

      $(document).on("click",'.button4',function(e){
        // var detail_pk = $(this).attr('pk');
        var suggestion_pk = $(this).attr('pk');
        var comment_id = $(this).attr('id');
        // console.log(detail_pk);
        // var data= $(this).serialize();
        console.log(comment_id);
        $.ajax({
            url: '/LevelSet/Suggestions/suggestion_comment_edit/'+comment_id+'/',
            type: 'get',
            success: function (data) {
                $('#hide_payment').show();
                $("#payments").after(data);
                $('#hide_payment').click(function(){
                    $("#payment_form").remove();
                    $('#hide_payment').hide();
                });
            }
        });
        });

Мои URL...

path("suggestion_comment_edit/<int:id>/",views.suggestion_comment_edit_view, name='suggestion_comment_edit'),

Я действительно пытался изменить URL, чтобы связать его с детальным просмотром, но это тоже не помогло...

В какой-то момент у меня было что-то вроде...

path("suggestion_by_name_detail/2c560fc6-f00e-455a-99ae-82b294a134d8/<uuid:pk>/<int:id>/",views.SuggestionByNameDetailView.as_view(), name='suggestion_by_name_detail'),

Чтобы получить и DetailView и ID комментария в одном URL, но, похоже, это не помогло.

Я уверен, что путаю некоторые вещи....Это почти дает мне то, что я хочу...Я могу отобразить блог с детальным просмотром...комментарий в верхней части работает так, как я хочу....Проблема в том, как заставить кнопку редактирования работать....Это немного странно, потому что я действительно вижу, что это вроде как работает в браузере. ...Если я нажимаю на ссылку в браузере Chrome, он действительно показывает мне комментарий в режиме редактирования.... и позволяет мне обновить его там.... Но на экране, если я просто делаю {{ форму )), он показывает мне пустое поле ввода.... Я открыт для UpdateView.... Я просто не мог понять это в этот момент...

Должно быть просто с минимальными изменениями в существующем коде

Добавьте PK в форму

  • Должен быть вводом, чтобы HTML-форма включала его внутрь сообщения
    • Я полагаю, что name attr - это все, что вам действительно нужно
  • Вы также можете отправить с помощью AJAX и включить пк из button4 attr
  • .
{% for comment in object.suggestion_comments.all %}
  <div class="spacer291">
    <p><a href="{% url 'Main:associate_directory_associate_detail' pk=comment.author.id %}">{{ comment.author }}</a> {{ comment.created_on }}</p>
    <p class="spacer290">{{ comment.comment }}</p>
      <div class="spacer289">
        <div class="upvote-comment-count">{{ comment.total_comment_upvotes }}</div>
        <button type="button" class="button6" data-href="{% url 'Suggestions:suggestion_comment_like' comment.id %}">Like</button>
        <button type="button" class="button2" data-href="">Reply</button>
        {% if comment.author == request.user %}
          <button type="button" class="button4" id="{{ comment.id }}" pk="{{ object.pk }}" href="{% url 'Suggestions:suggestion_comment_edit' comment.id %}">Edit</button>
          <div class="spacer159" id="hide_payment" style="display:none;">
            <form method='POST'>
              {% csrf_token %}

                <div style="display:none;">
                  <input type="number" name="pk" value="{{comment.pk}}"></input>
                </div>

                <div class="spacer284">
                  {{ form.comment }}
                </div>
              <button class="button7" type="submit">Submit</button>
            <form>
          </div>
            <button type="button" class="button3" data-href="{% url 'Suggestions:suggestion_delete' comment.id %}">Delete</button>  
        {% endif %}
      </div>
    </div>
{% endfor %}

Добавьте логику в представление для обработки правок

def post(self, request, *args, **kwargs):
    print('POST:', request.POST) # to make sure PK is being sent, Del after

    commentObj = None
    if request.POST.get('pk'):
        commentObj = SuggestionComment.objects.filter(pk=request.POST.get('pk'))

    form = SuggestionCommentForm(request.POST, instance=commentObj)

    if form.is_valid():
        new_comment = form.save(commit=False)
        new_comment.author = request.user
        new_comment.suggestion = self.get_object()
        new_comment.save()
        self.object = self.get_object()
        context = self.get_context_data(object=self.object)
        html = render_to_string('suggestion_comments.html', context, request=self.request)
        return JsonResponse({'form': html})
    else:
        form_errors = form.errors.as_json()
        response = HttpResponse(form_errors, status=400)
        response['content_type'] = 'application/json'
        return response
Вернуться на верх