Skip to content
Advertisement

Django search returning Exception Value: object of type ‘method’ has no len()

Pretty new to Django Rest Framework and I’m not quite sure how to debug this error at the moment. When I set a breakpoint in the view search view. I see all my products in results

<bound method QuerySet.distinct of <ProductQuerySet [<Product: Product object (4)>, <Product: Product object (8)>, <Product: Product object (9)>, <Product: Product object (10)>]>>

Pagination is set in settings.py

REST_FRAMEWORK = {
    "DEFAULT_AUTHENTICATION_CLASSES": [
        "rest_framework.authentication.SessionAuthentication",
        "api.authentication.TokenAuthentication",
    ],
    "DEFAULT_PERMISSION_CLASSES": [
        "rest_framework.permissions.IsAuthenticatedOrReadOnly",  # GET for everyone, all other calls need to be authenticated
    ],
    "DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.LimitOffsetPagination",
    "PAGE_SIZE": 10,
}

Search view

from rest_framework import generics

from products.models import Product
from products.serializers import ProductSerializer


class SearchListView(generics.ListAPIView):
    queryset = Product.objects.all()
    serializer_class = ProductSerializer

    def get_queryset(self, *args, **kwargs):
        qs = super().get_queryset(*args, **kwargs)
        q = self.request.GET.get("q")
        results = Product.objects.none()
        if q is not None:
            user = None
            if self.request.user.is_authenticated:
                user = self.request.user
            results = qs.search(q, user=user)
        return results

Products view

from rest_framework import generics, mixins
from django.shortcuts import get_object_or_404

from api.mixins import StaffEditorPermissionMixin, UserQuerySetMixin

from .models import Product
from .serializers import ProductSerializer

class ProductListCreateAPIView(
    UserQuerySetMixin, StaffEditorPermissionMixin, generics.ListCreateAPIView
):
    queryset = Product.objects.all()
    serializer_class = ProductSerializer

    def perform_create(self, serializer):
        title = serializer.validated_data.get("title")
        content = serializer.validated_data.get("content") or None
        if content is None:
            content = title
        serializer.save(user=self.request.user, content=content)

class ProductDetailAPIView(
    UserQuerySetMixin, StaffEditorPermissionMixin, generics.RetrieveAPIView
):
    queryset = Product.objects.all()
    serializer_class = ProductSerializer

Products model

from django.db import models
from django.conf import settings
from django.db.models import Q

User = settings.AUTH_USER_MODEL  # auth.User


class ProductQuerySet(models.QuerySet):
    def is_public(self):
        return self.filter(public=True)

    def search(self, query, user=None):
        lookup = Q(title__icontains=query) | Q(content__icontains=query)
        qs = self.is_public().filter(lookup)
        if user is not None:
            qs2 = self.filter(user=user).filter(lookup)
            qs = (qs | qs2).distinct
        return qs


class ProductManager(models.Manager):
    def get_queryset(self, *args, **kwargs):
        return ProductQuerySet(self.model, using=self._db)

    def search(self, query, user=None):
        return self.get_queryset().search(query, user=user)


class Product(models.Model):
    user = models.ForeignKey(User, default=1, null=True, on_delete=models.SET_NULL)
    title = models.CharField(max_length=120)
    content = models.TextField(blank=True, null=True)
    price = models.DecimalField(max_digits=15, decimal_places=2, default=99.99)
    public = models.BooleanField(default=True)

    objects = ProductManager()

    @property
    def sale_price(self):
        return "%.2f" % (float(self.price) * 0.8)

    # instance method
    def get_discount(self):
        return "122"

Below is the full trace of my error

Environment:


Request Method: GET
Request URL: http://localhost:8000/api/search/?q=he

Django Version: 4.0.5
Python Version: 3.10.5
Installed Applications:
['django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'rest_framework',
 'rest_framework.authtoken',
 'api',
 'products',
 'search']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']



Traceback (most recent call last):
  File "/Users/bradli/Development/learning/drf/venv/lib/python3.10/site-packages/rest_framework/pagination.py", line 525, in get_count
    return queryset.count()

During handling of the above exception ('function' object has no attribute 'count'), another exception occurred:
  File "/Users/bradli/Development/learning/drf/venv/lib/python3.10/site-packages/django/core/handlers/exception.py", line 55, in inner
    response = get_response(request)
  File "/Users/bradli/Development/learning/drf/venv/lib/python3.10/site-packages/django/core/handlers/base.py", line 197, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/Users/bradli/Development/learning/drf/venv/lib/python3.10/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "/Users/bradli/Development/learning/drf/venv/lib/python3.10/site-packages/django/views/generic/base.py", line 84, in view
    return self.dispatch(request, *args, **kwargs)
  File "/Users/bradli/Development/learning/drf/venv/lib/python3.10/site-packages/rest_framework/views.py", line 509, in dispatch
    response = self.handle_exception(exc)
  File "/Users/bradli/Development/learning/drf/venv/lib/python3.10/site-packages/rest_framework/views.py", line 469, in handle_exception
    self.raise_uncaught_exception(exc)
  File "/Users/bradli/Development/learning/drf/venv/lib/python3.10/site-packages/rest_framework/views.py", line 480, in raise_uncaught_exception
    raise exc
  File "/Users/bradli/Development/learning/drf/venv/lib/python3.10/site-packages/rest_framework/views.py", line 506, in dispatch
    response = handler(request, *args, **kwargs)
  File "/Users/bradli/Development/learning/drf/venv/lib/python3.10/site-packages/rest_framework/generics.py", line 199, in get
    return self.list(request, *args, **kwargs)
  File "/Users/bradli/Development/learning/drf/venv/lib/python3.10/site-packages/rest_framework/mixins.py", line 40, in list
    page = self.paginate_queryset(queryset)
  File "/Users/bradli/Development/learning/drf/venv/lib/python3.10/site-packages/rest_framework/generics.py", line 171, in paginate_queryset
    return self.paginator.paginate_queryset(queryset, self.request, view=self)
  File "/Users/bradli/Development/learning/drf/venv/lib/python3.10/site-packages/rest_framework/pagination.py", line 387, in paginate_queryset
    self.count = self.get_count(queryset)
  File "/Users/bradli/Development/learning/drf/venv/lib/python3.10/site-packages/rest_framework/pagination.py", line 527, in get_count
    return len(queryset)

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

Advertisement

Answer

You are missing () when trying to call .distinct() method in search()

User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement