首页 > 解决方案 > Python Django列出属于一个类别的所有帖子

问题描述

我想使用 python django 框架列出属于一个类别的所有帖子。

我认为最好的方法是使用 django.views.generic.ListView

我的模型:

class Category(models.Model):
    name = models.CharField(max_length=250)
    slug = models.SlugField(max_length=250, blank=True)

    def __str__(self):
        return self.name

    def get_absolute_url(self):
        kwargs = {
            'slug': self.slug
        }
        return reverse('category-detail', kwargs=kwargs)    

    def save(self, *args, **kwargs):
        value = self.name
        self.slug = slugify(value, allow_unicode=True)
        super().save(*args, **kwargs)

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)
    category = models.ForeignKey(Category, on_delete=models.CASCADE, blank=False)

    def __str__(self):
        return self.title

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

我的网址模式:

urlpatterns = [
    path('', PostListView.as_view(), name='blog-home'),
    path('category/<str:slug>/', CategoryListView.as_view(), name='category-detail'),
    path('post/<int:pk>/', PostDetailView.as_view(), name='post-detail')
]

我的观点:

class CategoryListView(ListView):
    paginate_by = 8
    template_name = 'blog/category_list.html'
    context_object_name = 'posts'

    def get_queryset(self):
        return Post.objects.filter(category_id=Category.objects.filter(slug=self.kwargs.get('slug')).first().id).all()

这对我有用。然而,这似乎不是最优雅的方式,因为我必须先获取 category_id 然后过滤帖子。

有没有更优雅的方法来做到这一点?

标签: pythondjangolistviewdetailview

解决方案


你能做到吗:

posts = Category.objects.get(slug=self.kwargs.get('slug')).post_set.all()

假设该slug字段是唯一的。

文档很好地描述了倒退: https ://docs.djangoproject.com/en/1.11/topics/db/queries/#following-relationships-backward

使用您的get_queryset()方法,使用 kwargs 可能值得多做一点防御:

def get_querset(self):
    category = get_object_or_404(Category, slug=self.kwargs.get('slug'))
    return category.post_set.all()

这样,如果将错误的 slug 传递到 url,它将返回 404 而不是DoesNotExist异常。


推荐阅读