在 Django 中为多个查询编写视图的最佳方法?

Posted

技术标签:

【中文标题】在 Django 中为多个查询编写视图的最佳方法?【英文标题】:Best way to write views for multiple queries in Django? 【发布时间】:2019-05-13 09:53:24 【问题描述】:

这是一个简单的问题。我已经组织了我的模型,以便提供给页面的大多数对象都是一种类型 - 项目。该模型包含各种属性,可以帮助我以不同的方式服务它。

我有文章和视频,它们由模型上的“类型”字段确定。类型 = '文章' 等。

我有一个列表视图,它显示了 Item 模型中的所有对象,按日期排序。

class ItemListView(generic.ListView):

    # This handles the logic for the UserForm and ProfileForm - without it, nothing happens.
    def item(self, request, *args, **kwargs):
        return index(request)

    def get_queryset(self):
        # return Post.objects.filter(published_date__lte=timezone.now()).order_by('-published_date')
        return Item.objects.all().order_by('-create_date')

我想要一个显示所有文章(按日期排序)和所有视频(按日期排序)的视图。我有一种感觉,我会写更多这样的观点。

有没有比为每个查询编写一个新视图更好的方法呢?因为,这就是我目前正在做的事情:

Views.py

class ItemListViewArticle(generic.ListView):

    # This handles the logic for the UserForm and ProfileForm - without it, nothing happens.
    def item(self, request, *args, **kwargs):
        return index(request)

    def get_queryset(self):
        # return Post.objects.filter(published_date__lte=timezone.now()).order_by('-published_date')
        return Item.objects.filter(type__contains='article').order_by('-create_date')

class ItemListViewVideo(generic.ListView):

    # This handles the logic for the UserForm and ProfileForm - without it, nothing happens.
    def item(self, request, *args, **kwargs):
        return index(request)

    def get_queryset(self):
        # return Post.objects.filter(published_date__lte=timezone.now()).order_by('-published_date')
        return Item.objects.filter(type__contains='video').order_by('-create_date')

urls.py

    path('new/', views.ItemListView.as_view(), name='new_list'),
    path('new/articles', views.ItemListViewArticle.as_view(), name='article_list'),
    path('new/videos', views.ItemListViewVideo.as_view(), name='video_list'),

【问题讨论】:

您发布的代码中没有任何内容会调用item 方法。除非您的问题中没有包含其他代码,否则您应该删除它。 我从模板的下拉列表中调用它们 - 一个指向视图的简单 href 链接。 这没有任何意义。您不能直接从模板调用方法 - 您的浏览器发出请求,Django 将其传递给视图,视图可以调用方法。如果您没有调用 item 方法的 Python 代码,那么它什么也做不了。 【参考方案1】:

您可以使用URL querystring(即request.GET) 从 url 中获取项目的类型并通过它进行过滤。像这样:

path('new/', views.ItemListView.as_view(), name='new_list'),


class ItemListViewArticle(generic.ListView):

    def item(self, request, *args, **kwargs):
        return index(request)

    def get_queryset(self):
        content_type = self.request.GET.get('type')
        return Item.objects.filter(type__contains=content_type).order_by('-create_date')

# usage
localhost:8000/new/?type=article
localhost:8000/new/?type=video

或者你可以使用URL parameter来获取数据的类型:

path('new/<str:content_type>/', views.ItemListView.as_view(), name='new_list'),

class ItemListViewArticle(generic.ListView):

    def item(self, request, *args, **kwargs):
        return index(request)

    def get_queryset(self):
        content_type = self.kwargs.get('content_type')
        return Item.objects.filter(type__contains=content_type).order_by('-create_date')

# usage
localhost:8000/new/article/
localhost:8000/new/video/

【讨论】:

谢谢 - 第二个选项效果很好。我以前没见过,所以这非常有用。从 URL 获取信息非常有用,它可以让视图中的内容更有条理! 酷。如果这个答案对你有帮助,那么请consider marking it as accepted :)

以上是关于在 Django 中为多个查询编写视图的最佳方法?的主要内容,如果未能解决你的问题,请参考以下文章

在 django 中为模型创造完整历史的最佳方法是啥?

在多个 django 模板文件中显示相同 html 块的最佳 DRY 方法

在Django REST List API视图中对原始SQL查询进行分页的最佳方法是什么?

在基于 Django 的 GraphQL API 中为 postgres 表创建全局搜索字段的最佳方法?

有没有办法可以在Django中的同一个模板中渲染多个视图?如果有最佳实践可以做到这一点?提前致谢

我应该如何在 Django 中为表单编写测试?