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()