Обработка ModelForms в представлениях
Мы будем использовать post detail view для создания экземпляра формы и обработаем ее так, чтобы ее упростить. Измените файл models.py, добавьте import для модели Comment и CommentForm форму, а затем измените представление post_detail, чтобы файл выглядел следующим образом:
from .models import Post, Comment
from .forms import EmailPostForm, CommentForm
def post_detail(request, year, month, day, post):
post = get_object_or_404(Post, slug=post,
status='published',
publish__year=year,
publish__month=month,
publish__day=day)
# List of active comments for this post
comments = post.comments.filter(active=True)
if request.method == 'POST':
# A comment was posted
comment_form = CommentForm(data=request.POST)
if comment_form.is_valid():
# Create Comment object but don't save to database yet
new_comment = comment_form.save(commit=False)
# Assign the current post to the comment
new_comment.post = post
# Save the comment to the database
new_comment.save()
else:
comment_form = CommentForm()
return render(request,
'blog/post/detail.html',
{'post': post,
'comments': comments,
'comment_form': comment_form})
Давайте рассмотрим то, что мы добавили к нашему представлению. Мы используем представление post_detail для отображения поста и его комментариев. Мы добавляем запрос(QuerySet) для получения всех активных комментариев для конткретного поста:
comments = post.comments.filter(active=True)
Мы начинаем строить запрос(QuerySet), начиная с объекта post. Мы используем manager для связанных объектов, определенных как comments, используя атрибут related_name связи в модели Comment.
Мы также используем одно и то же представление, чтобы позволить нашим пользователям добавить новый комментарий. Поэтому мы строим экземпляр формы с comment_form = CommentForm(), если представление вызывается запросом GET. Если запрос выполняется с помощью метода POST, то создается экземпляр формы с использованием отправленных данных и проверяется с помощью метода is_valid(). Если форма является невалидной, то в этом шаблоне отобразятся ошибки проверки. Если форма является валидной, выполняются следующие действия:
- Мы создаем новый объект Comment, вызвав метод формы save():
new_comment = comment_form.save(commit=False)
- Метод save() создает экземпляр модели, с которой связана форма, и сохраняет ее в базе данных. При вызове этого элемента с commit=False создается экземпляр модели, но не сохраняется в базе данных. Это очень удобно, когда требуется изменить объект до окончательного сохранения. Метод save() доступен для ModelForm, но не для экземпляров Form, поскольку они не связаны с какой-либо моделью.
- Мы присваиваем текущий пост только что созданному комментарию:
new_comment.post = post
При этом указывается, что новый комментарий принадлежит данной записи(посту).
- Наконец, мы сохраняем новый комментарий в базу данных следующим образом:
new_comment.save()
Теперь наше представление готово для отображения и обработки новых комментариев.