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
JavaScript
x
2
1
<bound method QuerySet.distinct of <ProductQuerySet [<Product: Product object (4)>, <Product: Product object (8)>, <Product: Product object (9)>, <Product: Product object (10)>]>>
2
Pagination is set in settings.py
JavaScript
1
12
12
1
REST_FRAMEWORK = {
2
"DEFAULT_AUTHENTICATION_CLASSES": [
3
"rest_framework.authentication.SessionAuthentication",
4
"api.authentication.TokenAuthentication",
5
],
6
"DEFAULT_PERMISSION_CLASSES": [
7
"rest_framework.permissions.IsAuthenticatedOrReadOnly", # GET for everyone, all other calls need to be authenticated
8
],
9
"DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.LimitOffsetPagination",
10
"PAGE_SIZE": 10,
11
}
12
Search view
JavaScript
1
21
21
1
from rest_framework import generics
2
3
from products.models import Product
4
from products.serializers import ProductSerializer
5
6
7
class SearchListView(generics.ListAPIView):
8
queryset = Product.objects.all()
9
serializer_class = ProductSerializer
10
11
def get_queryset(self, *args, **kwargs):
12
qs = super().get_queryset(*args, **kwargs)
13
q = self.request.GET.get("q")
14
results = Product.objects.none()
15
if q is not None:
16
user = None
17
if self.request.user.is_authenticated:
18
user = self.request.user
19
results = qs.search(q, user=user)
20
return results
21
Products view
JavaScript
1
27
27
1
from rest_framework import generics, mixins
2
from django.shortcuts import get_object_or_404
3
4
from api.mixins import StaffEditorPermissionMixin, UserQuerySetMixin
5
6
from .models import Product
7
from .serializers import ProductSerializer
8
9
class ProductListCreateAPIView(
10
UserQuerySetMixin, StaffEditorPermissionMixin, generics.ListCreateAPIView
11
):
12
queryset = Product.objects.all()
13
serializer_class = ProductSerializer
14
15
def perform_create(self, serializer):
16
title = serializer.validated_data.get("title")
17
content = serializer.validated_data.get("content") or None
18
if content is None:
19
content = title
20
serializer.save(user=self.request.user, content=content)
21
22
class ProductDetailAPIView(
23
UserQuerySetMixin, StaffEditorPermissionMixin, generics.RetrieveAPIView
24
):
25
queryset = Product.objects.all()
26
serializer_class = ProductSerializer
27
Products model
JavaScript
1
45
45
1
from django.db import models
2
from django.conf import settings
3
from django.db.models import Q
4
5
User = settings.AUTH_USER_MODEL # auth.User
6
7
8
class ProductQuerySet(models.QuerySet):
9
def is_public(self):
10
return self.filter(public=True)
11
12
def search(self, query, user=None):
13
lookup = Q(title__icontains=query) | Q(content__icontains=query)
14
qs = self.is_public().filter(lookup)
15
if user is not None:
16
qs2 = self.filter(user=user).filter(lookup)
17
qs = (qs | qs2).distinct
18
return qs
19
20
21
class ProductManager(models.Manager):
22
def get_queryset(self, *args, **kwargs):
23
return ProductQuerySet(self.model, using=self._db)
24
25
def search(self, query, user=None):
26
return self.get_queryset().search(query, user=user)
27
28
29
class Product(models.Model):
30
user = models.ForeignKey(User, default=1, null=True, on_delete=models.SET_NULL)
31
title = models.CharField(max_length=120)
32
content = models.TextField(blank=True, null=True)
33
price = models.DecimalField(max_digits=15, decimal_places=2, default=99.99)
34
public = models.BooleanField(default=True)
35
36
objects = ProductManager()
37
38
@property
39
def sale_price(self):
40
return "%.2f" % (float(self.price) * 0.8)
41
42
# instance method
43
def get_discount(self):
44
return "122"
45
Below is the full trace of my error
JavaScript
1
66
66
1
Environment:
2
3
4
Request Method: GET
5
Request URL: http://localhost:8000/api/search/?q=he
6
7
Django Version: 4.0.5
8
Python Version: 3.10.5
9
Installed Applications:
10
['django.contrib.admin',
11
'django.contrib.auth',
12
'django.contrib.contenttypes',
13
'django.contrib.sessions',
14
'django.contrib.messages',
15
'django.contrib.staticfiles',
16
'rest_framework',
17
'rest_framework.authtoken',
18
'api',
19
'products',
20
'search']
21
Installed Middleware:
22
['django.middleware.security.SecurityMiddleware',
23
'django.contrib.sessions.middleware.SessionMiddleware',
24
'django.middleware.common.CommonMiddleware',
25
'django.middleware.csrf.CsrfViewMiddleware',
26
'django.contrib.auth.middleware.AuthenticationMiddleware',
27
'django.contrib.messages.middleware.MessageMiddleware',
28
'django.middleware.clickjacking.XFrameOptionsMiddleware']
29
30
31
32
Traceback (most recent call last):
33
File "/Users/bradli/Development/learning/drf/venv/lib/python3.10/site-packages/rest_framework/pagination.py", line 525, in get_count
34
return queryset.count()
35
36
During handling of the above exception ('function' object has no attribute 'count'), another exception occurred:
37
File "/Users/bradli/Development/learning/drf/venv/lib/python3.10/site-packages/django/core/handlers/exception.py", line 55, in inner
38
response = get_response(request)
39
File "/Users/bradli/Development/learning/drf/venv/lib/python3.10/site-packages/django/core/handlers/base.py", line 197, in _get_response
40
response = wrapped_callback(request, *callback_args, **callback_kwargs)
41
File "/Users/bradli/Development/learning/drf/venv/lib/python3.10/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
42
return view_func(*args, **kwargs)
43
File "/Users/bradli/Development/learning/drf/venv/lib/python3.10/site-packages/django/views/generic/base.py", line 84, in view
44
return self.dispatch(request, *args, **kwargs)
45
File "/Users/bradli/Development/learning/drf/venv/lib/python3.10/site-packages/rest_framework/views.py", line 509, in dispatch
46
response = self.handle_exception(exc)
47
File "/Users/bradli/Development/learning/drf/venv/lib/python3.10/site-packages/rest_framework/views.py", line 469, in handle_exception
48
self.raise_uncaught_exception(exc)
49
File "/Users/bradli/Development/learning/drf/venv/lib/python3.10/site-packages/rest_framework/views.py", line 480, in raise_uncaught_exception
50
raise exc
51
File "/Users/bradli/Development/learning/drf/venv/lib/python3.10/site-packages/rest_framework/views.py", line 506, in dispatch
52
response = handler(request, *args, **kwargs)
53
File "/Users/bradli/Development/learning/drf/venv/lib/python3.10/site-packages/rest_framework/generics.py", line 199, in get
54
return self.list(request, *args, **kwargs)
55
File "/Users/bradli/Development/learning/drf/venv/lib/python3.10/site-packages/rest_framework/mixins.py", line 40, in list
56
page = self.paginate_queryset(queryset)
57
File "/Users/bradli/Development/learning/drf/venv/lib/python3.10/site-packages/rest_framework/generics.py", line 171, in paginate_queryset
58
return self.paginator.paginate_queryset(queryset, self.request, view=self)
59
File "/Users/bradli/Development/learning/drf/venv/lib/python3.10/site-packages/rest_framework/pagination.py", line 387, in paginate_queryset
60
self.count = self.get_count(queryset)
61
File "/Users/bradli/Development/learning/drf/venv/lib/python3.10/site-packages/rest_framework/pagination.py", line 527, in get_count
62
return len(queryset)
63
64
Exception Type: TypeError at /api/search/
65
Exception Value: object of type 'method' has no len()
66
Advertisement
Answer
You are missing ()
when trying to call .distinct()
method in search()