【问题标题】:Django object of type 'method' has no len()“方法”类型的 Django 对象没有 len()
【发布时间】:2023-04-01 21:56:01
【问题描述】:

我刚刚在 Django 中的 ListView 中添加了分页,但它返回 object of type 'method' has no len() 错误,即使我重写了 get_queryset 方法并且它没有返回与查询集不同的任何内容。

导致错误的视图如下所示:

class ProductList(ListView):
    paginate_by = 10
    model = Product
    context_object_name = 'products'
    template_name = 'catalog/product/product_list.html'

    @method_decorator(login_required)
    def dispatch(self, *args, **kwargs):
        return super().dispatch(*args, **kwargs)

    def queryset(self):
        categories = Category.objects.filter(company=self.request.user.profile.company)
        return Product.objects.filter(category__in=categories)

    def get_context_data(self, **kwargs):
        context = super(ProductList, self).get_context_data(**kwargs)
        context['customers'] = Customer.objects.filter(company=self.request.user.profile.company)
        context['categories'] = Category.objects.filter(company=self.request.user.profile.company)
        return context

完整的追溯:

Traceback (most recent call last):
  File "/home/ubuntu/dawipoenv/lib/python3.6/site-packages/django/core/handlers/exception.py", line 47, in inner
    response = get_response(request)
  File "/home/ubuntu/dawipoenv/lib/python3.6/site-packages/django/core/handlers/base.py", line 179, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/home/ubuntu/dawipoenv/lib/python3.6/site-packages/django/views/generic/base.py", line 70, in view
    return self.dispatch(request, *args, **kwargs)
  File "/home/ubuntu/dawipoenv/lib/python3.6/site-packages/django/utils/decorators.py", line 43, in _wrapper
    return bound_method(*args, **kwargs)
  File "/home/ubuntu/dawipoenv/lib/python3.6/site-packages/django/contrib/auth/decorators.py", line 21, in _wrapped_view
    return view_func(request, *args, **kwargs)
  File "/home/ubuntu/dawipo/catalog/views.py", line 105, in dispatch
    return super().dispatch(*args, **kwargs)
  File "/home/ubuntu/dawipoenv/lib/python3.6/site-packages/django/views/generic/base.py", line 98, in dispatch
    return handler(request, *args, **kwargs)
  File "/home/ubuntu/dawipoenv/lib/python3.6/site-packages/django/views/generic/list.py", line 157, in get
    context = self.get_context_data()
  File "/home/ubuntu/dawipo/catalog/views.py", line 113, in get_context_data
    context = super(ProductList, self).get_context_data(**kwargs)
  File "/home/ubuntu/dawipoenv/lib/python3.6/site-packages/django/views/generic/list.py", line 119, in get_context_data
    paginator, page, queryset, is_paginated = self.paginate_queryset(queryset, page_size)
  File "/home/ubuntu/dawipoenv/lib/python3.6/site-packages/django/views/generic/list.py", line 69, in paginate_queryset
    page = paginator.page(page_number)
  File "/home/ubuntu/dawipoenv/lib/python3.6/site-packages/django/core/paginator.py", line 73, in page
    number = self.validate_number(number)
  File "/home/ubuntu/dawipoenv/lib/python3.6/site-packages/django/core/paginator.py", line 51, in validate_number
    if number > self.num_pages:
  File "/home/ubuntu/dawipoenv/lib/python3.6/site-packages/django/utils/functional.py", line 48, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "/home/ubuntu/dawipoenv/lib/python3.6/site-packages/django/core/paginator.py", line 100, in num_pages
    if self.count == 0 and not self.allow_empty_first_page:
  File "/home/ubuntu/dawipoenv/lib/python3.6/site-packages/django/utils/functional.py", line 48, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "/home/ubuntu/dawipoenv/lib/python3.6/site-packages/django/core/paginator.py", line 95, in count
    return len(self.object_list)

Exception Type: TypeError at /catalog/list/
Exception Value: object of type 'method' has no len()

我应该如何在不显示此错误的情况下使用覆盖的查询集进行分页?

【问题讨论】:

  • 请显示完整的回溯
  • @WillemVanOnsem 好的,我把回溯放在那里。

标签: django django-models django-views django-templates


【解决方案1】:

你覆盖的方法是<b>get_</b>queryset(…) [Django-doc],而不是querysetqueryset是一个属性,你可以为此设置一个QuerySet对象,但不能使用queryset作为方法。因此,您将其实现为:

from django.contrib.auth.mixins import LoginRequiredMixin

class ProductList(LoginRequiredMixin, ListView):
    paginate_by = 10
    model = Product
    context_object_name = 'products'
    template_name = 'catalog/product/product_list.html'
    
    # use get_queryset, not queryset
    def get_queryset(self, *args, **kwargs):
        return super().get_queryset(*args, **kwargs).filter(
            category__company=self.request.user.profile.company
        )

    # …

注意:您可以将视图限制为基于类的视图,以向经过身份验证的用户提供 LoginRequiredMixin mixin [Django-doc].

【讨论】:

    猜你喜欢
    • 2022-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-21
    • 2013-03-14
    • 2022-01-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多