【问题标题】:Filtering Objects in Class based view Django using Query parameters?使用查询参数在基于类的视图 Django 中过滤对象?
【发布时间】:2015-11-04 18:43:11
【问题描述】:

我正在使用基于类的通用视图Listview 来列出所有对象。

我的意见.py:

class PostsList(ListView):
    model = Post
    template_name = "index.html"

我的 Urls.py:

urlpatterns = [
    url(r'^$',PostsList.as_view(), name = "home"),
] 

这给了我所有帖子的列表。现在我想根据Post 模型的某些字段过滤/排序 帖子,比如price。我需要自己写这个吗?如果是,我应该覆盖PostsLists 类的哪个方法? def get, def get_context ?

我看到 Listview 的 get 方法定义如下。我可以在其中直接将 URL 查询参数作为**kwargs 传递,或者我必须在我的类中覆盖下面的方法。

def get(self, request, *args, **kwargs):
    ....

【问题讨论】:

    标签: python django


    【解决方案1】:

    当使用 Django 的基于类的视图时,尽可能避免覆盖 get()post()。这些方法做了很多,如果你重写它们,你可能不得不复制很多内置的功能。您通常可以覆盖更具体的方法。

    在您的情况下,您可以使用 get_queryset 方法动态过滤查询集。您可以使用self.request.GET 访问 GET 参数。例如:

    class PostsList(ListView):
        model = Post
    
        def get_queryset(self):
            """Filter by price if it is provided in GET parameters"""
            queryset = super(PostsList, self).get_queryset()
            if 'price' in self.request.GET:
                queryset = queryset.filter(price=self.request.GET['price'])
            return queryset
    

    如果您的网址捕获参数,您可以使用self.args(位置)和self.kwargs(基于名称)访问它们。

    有关更多信息,请参阅dynamic filtering 上的文档。

    【讨论】:

    • 另外:您可以使用 self.argsself.kwargs 从 URL 访问 args 和 kwargs
    • 出现了一些错误:get_queryset() takes exactly 2 arguments (1 given)
    • 首先它说request 对象未定义。所以我把它作为一个参数放在def get_queryset(self, request) 中,然后一个新的错误来了:get_queryset() takes exactly 2 arguments (1 given)
    • 另外,我正在记录 logger.debug(self.kwargs), logger.debug(self.args) 并在 url 中将查询参数作为 ?title=1984 传递,它们在记录中为空。
    • 应该是self.request,而不是request。我已经修复了上面的代码。您应该从 def get_request(self) 中删除 request
    【解决方案2】:

    您可以覆盖 get_queryset 方法:

    保留您可以在 url kwargs 中获取的所有参数的映射。

    def get_queryset(self):
        queryset = Post.objects.all()
    
        if self.request.GET.get('price'):
            queryset = queryset.filter(price=self.request.GET.get('price'))
        return queryset
    

    【讨论】:

    • 它只需要一个参数。您可以在此处查看 get_queryset 的原始代码。 github.com/django/django/blob/master/django/views/generic/…
    • 是的,你是对的。我添加了一个请求参数,后来删除了它。现在它正在工作。
    • 如何在后端访问 url 查询参数? self.request.GET.get 是一种方式。我可以使用self.argsself.kwargs
    • 取决于您的 url 方案。假设你的 url 是这样的:posts/<post_value>/,你可以像self.kwargs.get('post_value') 一样访问get_queryset 中的 post_value。因此,您可以过滤您的查询集,例如 queryset = queryset.filter(price=self.kwargs.get('price_value'))
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-01-08
    • 2019-03-14
    • 2016-08-27
    • 2016-03-31
    • 2018-11-19
    • 1970-01-01
    • 2015-04-30
    相关资源
    最近更新 更多