我的董事会观点:
class BoardListView(ListView):
model = Board
context_object_name = 'boards'
template_name = 'home.html'
class TopicListView(ListView):
model = Topic
context_object_name = 'topics'
template_name = 'topics.html'
paginate_by = 5
def get_context_data(self, **kwargs):
kwargs['board'] = self.board
return super().get_context_data(**kwargs)
def get_queryset(self):
self.board = get_object_or_404(Board, pk=self.kwargs.get('pk'))
queryset = self.board.topics.order_by('-last_updated').annotate(replies=Count('posts') - 1)
return queryset
@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)
topic.board = board
topic.starter = request.user # <- here
topic.save()
Post.objects.create(
message=form.cleaned_data.get('message'),
topic=topic,
created_by=request.user # <- and here
)
return redirect('topic_posts', pk=pk, topic_pk=topic.pk) # TODO: redirect to the created topic page
else:
form = NewTopicForm()
return render(request, 'new_topic.html', {'board': board, 'form': form})
def topic_posts(request, pk, topic_pk):
topic = get_object_or_404(Topic, board__pk=pk, pk=topic_pk)
topic.views += 1
topic.save()
return render(request, 'topic_posts.html', {'topic': 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()
topic.last_updated = timezone.now()
topic.save()
topic_url = reverse('topic_posts', kwargs={'pk': pk, 'topic_pk': topic_pk})
topic_post_url = '{url}?page={page}#{id}'.format(
url=topic_url,
id=post.pk,
page=topic.get_page_count()
)
return redirect(topic_post_url)
else:
form = PostForm()
return render(request, 'reply_topic.html', {'topic': topic, 'form': form})
@method_decorator(login_required, name='dispatch')
class PostUpdateView(UpdateView):
model = Post
fields = ('message', )
template_name = 'edit_post.html'
pk_url_kwarg = 'post_pk'
context_object_name = 'post'
def get_queryset(self):
queryset = super().get_queryset()
return queryset.filter(created_by=self.request.user)
def form_valid(self, form):
post = form.save(commit=False)
post.updated_by = self.request.user
post.updated_at = timezone.now()
post.save()
return redirect('topic_posts', pk=post.topic.board.pk, topic_pk=post.topic.pk)
class PostListView(ListView):
model = Post
context_object_name = 'posts'
template_name = 'topic_posts.html'
paginate_by = 20
def get_context_data(self, **kwargs):
session_key = 'viewed_topic_{}'.format(self.topic.pk)
if not self.request.session.get(session_key, False):
self.topic.views += 1
self.topic.save()
self.request.session[session_key] = True
kwargs['topic'] = self.topic
return super().get_context_data(**kwargs)
def get_queryset(self):
self.topic = get_object_or_404(Topic, board__pk=self.kwargs.get('pk'), pk=self.kwargs.get('topic_pk'))
queryset = self.topic.posts.order_by('created_at')
return queryset
和models.py:
from django.db import models
from django.contrib.auth.models import User
from django.utils.text import Truncator
import math
class Board(models.Model):
name = models.CharField(max_length=30, unique=True)
description = models.CharField(max_length=100)
def __str__(self):
return self.name
def get_posts_count(self):
return Post.objects.filter(topic__board=self).count()
def get_last_post(self):
return Post.objects.filter(topic__board=self).order_by('-created_at').first()
class Topic(models.Model):
subject = models.CharField(max_length=255)
last_updated = models.DateTimeField(auto_now_add=True)
board = models.ForeignKey(Board, on_delete=models.CASCADE, related_name='topics')
starter = models.ForeignKey(User, on_delete=models.CASCADE, related_name='topics')
views = models.PositiveIntegerField(default=0) # <- here
def __str__(self):
return self.subject
def get_page_count(self):
count = self.posts.count()
pages = count / 20
return math.ceil(pages)
def has_many_pages(self, count=None):
if count is None:
count = self.get_page_count()
return count > 6
def get_page_range(self):
count = self.get_page_count()
if self.has_many_pages(count):
return range(1, 5)
return range(1, count + 1)
def get_last_ten_posts(self):
return self.posts.order_by('-created_at')[:10]
class Post(models.Model):
message = models.TextField(max_length=4000)
topic = models.ForeignKey(Topic, on_delete=models.CASCADE, related_name='posts')
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(null=True)
created_by = models.ForeignKey(User, on_delete=models.CASCADE, related_name='posts')
updated_by = models.ForeignKey(User, on_delete=models.CASCADE, null=True, related_name='+')
def __str__(self):
truncated_message = Truncator(self.message)
return truncated_message.chars(30)