基于 Django Class 的视图:使用模型中的选项显示查询集

Django Class-based views: displaying queryset using choices from a model

我是 Django 的新手,因此我的知识有一些不足,尤其是在视图中的 get_context_data() 方面。我的目标是尝试利用 Django 的 DRY 方面,以便我在我的网页上有一个类别列表,每个类别显示属于它的 posts 列表。为此,我有一个 ListView 和 DetailView class(如下所示)。请注意,类别和 posts 都是同一模型的对象。 我的问题如下:

  1. 我只想在我的 ListView 中显示部分 post,而不是全部。有动态的方法来做到这一点吗?
  2. 在我的 DetailView 中,我想显示 post 的列表,但是从一个单一的选择中,例如说在创建 post 时选择了 choice1,那么只有所有 [=40=将显示选择了选项 1 的 ]s。我想动态地这样做,目前它被硬编码为只显示 choice1。我曾尝试使用 get_context_data() 来执行此操作,但这只会在我的模板中输出一个查询集,这导致我遇到问题 3
  3. 我的 HTML 文件当前将所有 post 选项 1 显示为查询集,但不是实际内容

Views.py

class PostListView(ListView):
    model = Post 
    template_name = 'blog/post.html'
    context_object_name = 'posts'   
    ordering = ['-date_posted']


class PostDetailView(DetailView):
    model = Post

def get_context_data(self, *args, **kwargs):
    context = super(PostDetailView, self).get_context_data(*args, **kwargs)
    list_of_relevant_articles = Post.objects.filter(choice = "choice1")
    context.update({'list_of_relevant_articles': list_of_relevant_articles})
    return context

Models.py

POST_CHOICES = (
    ('choice1','CHOICE1'),
    ('choice2', 'CHOICE2'),
    ('choice3','CHOICE3'),
    ('choice4','CHOICE4'),
)

class Post(models.Model):
    title = models.CharField(max_length=100)
    content = models.TextField()
    date_posted = models.DateTimeField(default=timezone.now)
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    image = models.ImageField(blank=True, null=True)
    choice = models.CharField(max_length=14, choices = POST_CHOICES, default ='choice1')


def __str__(self):
    return self.title

def get_absolute_url(self):
    return reverse('blog-post', kwargs={'pk': self.pk})

Html 文件

{% block content %}
<!-- This for loop does not output anything but I believe i need one to iterate through 
 a queryset-->
{% for post in object_list %}
    {{ list_of_relevant_articles }}
{% endfor %}

{% endblock content %}

任何 help/advice 将不胜感激

1

可以在模板中使用context['posts'] = context['posts'][:3]和普通循环,但一般情况下最好使用分页。

class PostListView(ListView):
    model = Post 
    template_name = 'blog/post.html'
    context_object_name = 'posts'   
    ordering = ['-date_posted']
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['posts'] = context['posts'][:3]
        return context

{% for post in posts %}
    {{ post }} <br>
{% endfor %}

另一种方法是不使用 get_context_data 并在模板内部使用切片,如:

{% for post in posts|slice:":2" %}

2, 3

class PostDetailView(DetailView):
    model = Post
    template_name = 'blog/detail.html'
    slug_url_kwarg = "choice"
    slug_field = "choice"
    context_object_name = 'posts'   
    def get_object(self, queryset=None):
        return Post.objects.filter(choice=self.kwargs.get("choice"))
{% for post in posts %}
    {{ post }} <br>
{% endfor %}

urls.py

urlpatterns = [
    # ...
    path('post/', views.PostListView.as_view(), name='list'),
    path('post/<str:choice>/', views.PostDetailView.as_view(), name='detail'),
]

因此在浏览器中:.../post/choice2/.../post/choice3/、...