Как я могу позволить пользователю редактировать комментарии в 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