ویوی پاسخ به پست
سلام
در این قسمت می خواهیم برای ارسال پاسخ به یک پست مشخص، ویوی جدید بسازیم.

یک آدرس جدید اضافه می کنیم.
myproject/urls.py
url(r'^boards/(?P<pk>\d+)/topics/(?P<topic_pk>\d+)/reply/$', views.reply_topic, name='reply_topic'),
یک فرم جدید برای پاسخ به پست می سازیم.
boards/forms.py (مشاهده کد کامل)
from django import forms
from .models import Post
class PostForm(forms.ModelForm):
class Meta:
model = Post
fields = ['message', ]
ویوی جدید توسط login_required@ محافظت می شود.
boards/views.py (مشاهده کد کامل)
from django.contrib.auth.decorators import login_required
from django.shortcuts import get_object_or_404, redirect, render
from .forms import PostForm
from .models import Topic
@login_required
def reply_topic(request, pk, topic_pk):
topic = get_object_or_404(Topic, board__pk=pk, pk=topic_pk)
if request.method == 'POST':
form = PostForm(request.POST)
if form.is_valid():
post = form.save(commit=False)
post.topic = topic
post.created_by = request.user
post.save()
return redirect('topic_posts', pk=pk, topic_pk=topic_pk)
else:
form = PostForm()
return render(request, 'reply_topic.html', {'topic': topic, 'form': form})
حالا باید ریدایرکت تابع ویوی new_topic را بروزرسانی کنیم. (همان قسمتی که با TO DO# به شکل کامنت درآمده بود.)
@login_required
def new_topic(request, pk):
board = get_object_or_404(Board, pk=pk)
if request.method == 'POST':
form = NewTopicForm(request.POST)
if form.is_valid():
topic = form.save(commit=False)
# code suppressed ...
return redirect('topic_posts', pk=pk, topic_pk=topic.pk) #TO DO <- here
# code suppressed ...
نکتۀ مهم: در ویوی reply_topic از topic_pk استفاده می کنیم چون قرار است به آرگومانی از تابع ارجاع دهیم و این در حالی است که در ویوی new_topic از topic.pk استفاده می کنیم چراکه topic یک شی یا object از مدل Topicبوده و استفاده از pk. امکان دسترسی به متعلقات مدل تاپیک را فراهم می کند. جزئیات ریز و تفاوت های بزرگ!!
اولین نسخه از قالب با محتوای زیر خواهد بود:
templates/reply_topic.html
{% extends 'base.html' %}
{% load static %}
{% block title %}Post a reply{% endblock %}
{% block breadcrumb %}
<li class="breadcrumb-item"><a href="{% url 'home' %}">Boards</a></li>
<li class="breadcrumb-item"><a href="{% url 'board_topics' topic.board.pk %}">{{ topic.board.name }}</a></li>
<li class="breadcrumb-item"><a href="{% url 'topic_posts' topic.board.pk topic.pk %}">{{ topic.subject }}</a></li>
<li class="breadcrumb-item active">Post a reply</li>
{% endblock %}
{% block content %}
<form method="post" class="mb-4">
{% csrf_token %}
{% include 'includes/form.html' %}
<button type="submit" class="btn btn-success">Post a reply</button>
</form>
{% for post in topic.posts.all %}
<div class="card mb-2">
<div class="card-body p-3">
<div class="row mb-3">
<div class="col-6">
<strong class="text-muted">{{ post.created_by.username }}</strong>
</div>
<div class="col-6 text-right">
<small class="text-muted">{{ post.created_at }}</small>
</div>
</div>
{{ post.message }}
</div>
</div>
{% endfor %}
{% endblock %}

بعد از ارسال پاسخ، کاربر به پست های تاپیک انتقال می یابد.

حالا می توانیم ایجاد کننده و مالک یک پست را تغییر دهیم و در خروجی نام او را مشخص کنیم.
templates/topic_posts.html (مشاهده کد کامل)
{% for post in topic.posts.all %}
<div class="card mb-2 {% if forloop.first %}border-dark{% endif %}">
{% if forloop.first %}
<div class="card-header text-white bg-dark py-2 px-3">{{ topic.subject }}</div>
{% endif %}
<div class="card-body p-3">
<!-- code suppressed -->
</div>
</div>
{% endfor %}

حالا برای نوشتن فایل تست یک فایل جدید با نام test_view_reply_topic.py را درون فولدر boards/tests ایجاد می کنیم.
boards/tests/test_view_reply_topic.py (مشاهده کد کامل)
from django.contrib.auth.models import User
from django.test import TestCase
from django.urls import reverse
from ..models import Board, Post, Topic
from ..views import reply_topic
class ReplyTopicTestCase(TestCase):
'''
Base test case to be used in all `reply_topic` view tests
'''
def setUp(self):
self.board = Board.objects.create(name='Django', description='Django board.')
self.username = 'john'
self.password = '123'
user = User.objects.create_user(username=self.username, email='john@doe.com', password=self.password)
self.topic = Topic.objects.create(subject='Hello, world', board=self.board, starter=user)
Post.objects.create(message='Lorem ipsum dolor sit amet', topic=self.topic, created_by=user)
self.url = reverse('reply_topic', kwargs={'pk': self.board.pk, 'topic_pk': self.topic.pk})
class LoginRequiredReplyTopicTests(ReplyTopicTestCase):
# ...
class ReplyTopicTests(ReplyTopicTestCase):
# ...
class SuccessfulReplyTopicTests(ReplyTopicTestCase):
# ...
class InvalidReplyTopicTests(ReplyTopicTestCase):
# ...
مورد اصلی مربوط به تست در این قطعه کد، کلاس ReplyTopicTestCase است. در مرحله بعدی می خواهیم چهار کلاس دیگر آن را توسعه دهیم.
در ابتدا دکوراتور login_required@ را بررسی و سپس کدهای وضعیت و وروردی های html را چک می کنیم. در نهایت نیز یک بار فرم را به صورت معتبر و بار دیگر به صورت نامعتبر ارسال می کنیم.
ترجمۀ اختصاصی توسط تمدن
مطلب بعدی: QuerySets
مطلب قبلی: ویوی پست های یک تاپیک

دیدگاه خود را ثبت کنید
تمایل دارید در گفتگو شرکت کنید؟نظری بدهید!