Django入门与实践-第20章:QuerySets(查询结果集)(完结)
#boards/models.py from django.utils.text import Truncator
class Topic(models.Model): # ... def __str__(self): return self.subject class Post(models.Model): # ... def __str__(self): truncated_message = Truncator(self.message) return truncated_message.chars(30)
python manage.py shell from boards.models import Board # First get a board instance from the database board = Board.objects.get(name='Django') board.topics.all() board.topics.count() #现在统计一个版块下面的回复数量有点麻烦,因为回复并没有和 Board 直接关联 from boards.models import Post Post.objects.all() Post.objects.count() 这里一共11个回复,但是它并不全部属于 "Django" 这个版块的。我们可以这样来过滤 from boards.models import Board, Post board = Board.objects.get(name='Django') Post.objects.filter(topic__board=board) Post.objects.filter(topic__board=board).count() 最后一个任务是标识版块下面的最后一条回复 Post.objects.filter(topic__board=board).order_by('-created_at') Post.objects.filter(topic__board=board).order_by('-created_at').first() #boards/models.py class Board(models.Model): 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() <--templates/home.html--> <!--以下代码应该在<small></small>中但是未通过--> <a href="{% url 'topic_posts' board.pk post.topic.pk %}"> By {{ post.created_by.username }} at {{ post.created_at }} </a> {% extends 'base.html' %} {% block breadcrumb %} <li class="breadcrumb-item active">Boards</li> {% endblock %} {% block content %} <table class="table"> <thead class="thead-inverse"> <tr> <th>Board</th> <th>Posts</th> <th>Topics</th> <th>Last Post</th> </tr> </thead> <tbody> {% for board in boards %} <tr> <td> <a href="{% url 'board_topics' board.pk %}">{{ board.name }}</a> <small class="text-muted d-block">{{ board.description }}</small> </td> <td class="align-middle">{{ board.get_posts_count }}</td> <td class="align-middle">{{ board.topics.count }}</td> <td class="align-middle"> {% with post=board.get_last_post %} <small> </small> {% endwith %} </td> </tr> {% endfor %} </tbody> </table> {% endblock %}
<!--看起来好像有问题,如果没有回复的时候程序会崩溃--> <!--templates/home.html--> {% with post=board.get_last_post %} {% if post %} <small> <a href="{% url 'topic_posts' board.pk post.topic.pk %}"> By {{ post.created_by.username }} at {{ post.created_at }} </a> </small> {% else %} <small class="text-muted"> <em>No posts yet.</em> </small> {% endif %} {% endwith %}
python manage.py shell from django.db.models import Count from boards.models import Board board = Board.objects.get(name='Django') topics = board.topics.order_by('-last_updated').annotate(replies=Count('posts')) for topic in topics: print(topic.replies) #我们来做一个小小的修复,因为回复里面不应该包括发起者的帖子 topics = board.topics.order_by('-last_updated').annotate(replies=Count('posts') - 1) for topic in topics: print(topic.replies)
#boards/views.py 更新 from django.db.models import Count def board_topics(request, pk): board = get_object_or_404(Board, pk=pk) topics = board.topics.order_by('-last_updated').annotate(replies=Count('posts') - 1) return render(request, 'topics.html', {'board': board, 'topics': topics}) <!--templates/topics.html--> {% for topic in topics %} <tr> <td><a href="{% url 'topic_posts' board.pk topic.pk %}">{{ topic.subject }}</a></td> <td>{{ topic.starter.username }}</td> <td>{{ topic.replies }}</td> <td>0</td> <td>{{ topic.last_updated }}</td> </tr> {% endfor %}