Локальная переменная 'comment_form' ссылается перед присвоением в django
Я создал приложение, в котором пользователь может войти в систему и опубликовать содержимое, которое он хочет: и теперь я решил добавить раздел комментариев к каждому сообщению, которое пользователь сделал в приложении, я следовал руководству на сайте djangocentral, но это не работает после того, как я добавил все, что они сделали в моем приложении, когда я нажимаю на [Читать далее], это бросает мне ошибку в браузере: локальная переменная 'comment_form' ссылается до назначения, если я удалил: 'comment_form' в контексте моего представления viewPhoto, то в шаблоне viewPhoto ничего не отображается. Как я могу это сделать?
модель:
class Comment(models.Model):
post = models.ForeignKey(Photo, on_delete=models.CASCADE, related_name='comments')
name = models.CharField(max_length=80)
email = models.EmailField()
body = models.TextField()
created_on = models.DateTimeField(auto_now_add=True)
active = models.BooleanField(default=False)
class Meta:
ordering = ['created_on']
def __str__(self):
return 'Comment {} by {}'.format(self.body, self.name)
в файле admin.py:
from django.contrib import admin
from .models import Photo, Category, Comment
# Register your models here.
admin.site.register(Category)
admin.site.register(Photo)
@admin.register(Comment)
class CommentAdmin(admin.ModelAdmin):
list_display = ('name', 'body', 'post', 'created_on', 'active')
list_filter = ('active', 'created_on')
search_fields = ('name', 'email', 'body')
actions = ['approve_cooments']
def approve_comment(self, request, queryset):
queryset.update(active=True)
the form.py:
from dataclasses import fields
from pyexpat import model
from .models import Comment
from django import forms
class CommentForm(forms.ModelForm):
class Meta:
model = Comment
fields = ('name', 'email', 'body',)
view.py:
def viewPhoto(request, pk):
post = get_object_or_404(Photo, id=pk)
photo = Photo.objects.get(id=pk)
template_name = 'photo.html'
comment = post.comments.filter(active=True)
new_comment = None
if request.method == 'POST':
comment_form = CommentForm(data=request.POST)
if comment_form.is_valid():
new_comment = comment_form.save(commit=False)
new_comment.post = post
new_comment.save()
else:
comment_form = CommentForm()
return render(request, 'photo.html', {'photo': photo, 'post': post,
'comment':comment,
'new_comment': new_comment,
'comment_form': comment_form})
viewPhoto template:
<body class="m-5">
<div class="container">
<div class="row justify-content-center">
<div class="col">
<div style="height: 90vh;">
<img style="max-width: 100%; max-height: 100%" src="{{ post.image.url }}" alt="">
<p>{{post.description}}</p>
<p>{{post.user.username.upper}}</p>
<p>{{post.date_added}}</p>
</div>
</div>
</div>
</div>
<div class="container">
{% for comment in comments %}
<p>{{ comment.name }}</p>
<br>
<p>{{ comment.created_on }}</p>
<br>
<p>{{ comment.body }}</p>
{% endfor %}
</div>
<div class="container">
{% if new_comments %}
<p>wait your comments is ready</p>
<form method="POST">
{% csrf_token %}
{{ comment_form.as_p }}
<button type="submit">submit</button>
</form>
{% endif %}
</div>
<1>> должен связываться с проверкой else, а не с проверкой if request.method == 'POST', поэтому:if comment_form.is_valid()
from django.shortcuts import redirect
def viewPhoto(request, pk):
post = get_object_or_404(Photo, id=pk)
photo = Photo.objects.get(id=pk)
template_name = 'photo.html'
comment = post.comments.filter(active=True)
new_comment = None
if request.method == 'POST':
comment_form = CommentForm(data=request.POST)
if comment_form.is_valid():
comment_form.instance.post = post
comment_form.save()
return redirect('name-of-some-view')
else:
comment_form = CommentForm()
return render(request, 'photo.html', {'photo': photo, 'post': post,
'comment':comment,
'new_comment': new_comment,
'comment_form': comment_form})
Примечание: В случае успешного POST запроса, вы должны сделать
redirect. [Django-doc] для реализации паттерна Post/Redirect/Get [wiki]. Это позволяет избежать повторения POST-запроса, когда пользователь обновляет браузер. браузер.
Думаю, я смогу вам помочь. Это довольно просто - вывести комментарий во фронтенде. Вы либо получаете комментарий по связанному имени, либо просто получаете его из модели комментария. Django - это простота и написание чистого кода Мое решение:
from django.shortcuts import redirect
def viewPhoto(request,pk):
# We are getting the comment by related name ('comments')
post = Photo.objects.prefetch_related('comments').get(pk=pk)
# Here is where we make the comment logic
if request.method == 'POST':
comment_form = CommentForm(request.POST)
if comment_form.is_valid():
new_comment = comment_form.save(commit=False)
comment_form.instance.post = post
new_comment.save()
# here you redirect after form have been saved to another view
return redirect('home') # would redirect to your home if have a home url name.
else:
comment_form = CommentForm()
return render(request,'photo.html/',{'post': post,'comment_form':comment_form})
Нам пришлось бы поработать над вашим шаблоном, чтобы изменить html-рендеринг комментариев и сообщений. Всегда хорошо, когда все просто и чисто.
body class="m-5">
<div class="container">
<div class="row justify-content-center">
<div class="col">
<div style="height: 90vh;">
<img style="max-width: 100%; max-height: 100%" src="{{ post.image.url }}" alt="">
<p>{{post.description}}</p>
<p>{{post.user.username}}</p>
<p>{{post.date_added}}</p>
</div>
</div>
</div>
</div>
<div class="container">
{% for comment in post.comments.all %}
<p>{{ comment.name }}</p>
<br>
<p>{{ comment.created_on }}</p>
<br>
<p>{{ comment.body }}</p>
{% endfor %}
</div>
<div class="container">
{% if new_comments %}
<p>wait your comments is ready</p>
<form method="POST">
{% csrf_token %}
{{ comment_form.as_p }}
<button type="submit">submit</button>
</form>
{% endif %}
</div>