ValueError at /books/results/ - django

"Field 'id' expected a number but got 'results'."
I'm getting this error while trying to use search filter over a list of books. It was working fine until I changed the Class-based view to Function based view.
This was the Class based view earlier using the default DetailView class:
class BookDetailView(LoginRequiredMixin,DetailView):
model = models.Book
template_name='book_detail.html'
login_url='login'
This is the new Function based detail view I changed to:
#login_required
def book_detail(request,book_id):
model =models.Book
book=model.objects.get(id=book_id)
template ='book_detail.html'
owner =CustomUser.objects.get(username=book.owner)
return render(request,template,{'book':book,'owner':owner})
Independently when I'm trying to go to detail view, its working fine. But when I try to search using the 'book_search' view, its throwing this error. Previously search functionality was also working fine.
#login_required
def book_search(request):
template ='book_list.html'
model =models.Book
query =request.GET.get('q')
results =model.objects.exclude(owner =request.user).order_by('-available','-id')
if query:
results =results.filter(Q(title__icontains =query))
paginator = Paginator(results, 9)
page =request.GET.get('page')
try:
books =paginator.page(page)
except PageNotAnInteger:
books =paginator.page(1)
except EmptyPage:
books= paginator.page(paginator.num_pages)
return render(request,template,{'books':books,'query':query,'page':page})
It has something to do with the result set that the search view is returning a list of books while detail view only require just one id.
Edit: Error stack:-
ValueError: invalid literal for int() with base 10: 'results'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "C:\Users\Dell\.virtualenvs\read_bus-VVRhbVr5\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
response = get_response(request)
File "C:\Users\Dell\.virtualenvs\read_bus-VVRhbVr5\lib\site-packages\django\core\handlers\base.py", line 115, in _get_response
response = self.process_exception_by_middleware(e, request)
File "C:\Users\Dell\.virtualenvs\read_bus-VVRhbVr5\lib\site-packages\django\core\handlers\base.py", line 113, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\Dell\.virtualenvs\read_bus-VVRhbVr5\lib\site-packages\django\contrib\auth\decorators.py", line 21, in _wrapped_view
return view_func(request, *args, **kwargs)
File "C:\Users\Dell\Documents\read_bus\books\views.py", line 216, in book_detail
book=results.get(id=book_id)
File "C:\Users\Dell\.virtualenvs\read_bus-VVRhbVr5\lib\site-packages\django\db\models\query.py", line 404, in get
clone = self._chain() if self.query.combinator else self.filter(*args, **kwargs)
File "C:\Users\Dell\.virtualenvs\read_bus-VVRhbVr5\lib\site-packages\django\db\models\query.py", line 904, in filter
return self._filter_or_exclude(False, *args, **kwargs)
File "C:\Users\Dell\.virtualenvs\read_bus-VVRhbVr5\lib\site-packages\django\db\models\query.py", line 923, in _filter_or_exclude
clone.query.add_q(Q(*args, **kwargs))
File "C:\Users\Dell\.virtualenvs\read_bus-VVRhbVr5\lib\site-packages\django\db\models\sql\query.py", line 1337, in add_q
clause, _ = self._add_q(q_object, self.used_aliases)
File "C:\Users\Dell\.virtualenvs\read_bus-VVRhbVr5\lib\site-packages\django\db\models\sql\query.py", line 1365, in _add_q
split_subq=split_subq, simple_col=simple_col,
File "C:\Users\Dell\.virtualenvs\read_bus-VVRhbVr5\lib\site-packages\django\db\models\sql\query.py", line 1298, in build_filter
condition = self.build_lookup(lookups, col, value)
File "C:\Users\Dell\.virtualenvs\read_bus-VVRhbVr5\lib\site-packages\django\db\models\sql\query.py", line 1155, in build_lookup
lookup = lookup_class(lhs, rhs)
File "C:\Users\Dell\.virtualenvs\read_bus-VVRhbVr5\lib\site-packages\django\db\models\lookups.py", line 22, in __init__
self.rhs = self.get_prep_lookup()
File "C:\Users\Dell\.virtualenvs\read_bus-VVRhbVr5\lib\site-packages\django\db\models\lookups.py", line 72, in get_prep_lookup
return self.lhs.output_field.get_prep_value(self.rhs)
File "C:\Users\Dell\.virtualenvs\read_bus-VVRhbVr5\lib\site-packages\django\db\models\fields\__init__.py", line 1772, in get_prep_value
) from e

For this detail_view:
URLs should look like:
urlpatterns =[
path('book/<int:pk>',views.book_detail,name ='book_detail'),
path('results/',views.book_search,name ='search'),
]
While the views function should be this:
#login_required
def book_detail(request,book_id):
model =models.Book
book=model.objects.get(id=book_id)
template ='book_detail.html'
owner =CustomUser.objects.get(username=book.owner)
return render(request,template,{'book':book,'owner':owner})
Passing value as http://127.0.0.1:8000/api/book/1

I seem to have found the solution.
It was actually the url pattern for the 'book_detail' that was causing the problem. I had created it without using path converter
urls.py:
...
urlpatterns =[
path('<book_id>/',views.book_detail,name ='book_detail'),
path('results/',views.book_search,name ='search'),
]
I thought just using <book_id> would suffice, and since it is higher in the hierarchy
of urlpatterns, it was matched for 'results' too.
Changing the path to <int:book_id> worked. Now I've realised the significance of the little path converter and won't ever forget using this.

Related

Django: Strange error with connection between view, template and url

I have two main usage and main model pages, in which products from a specific usage or model are listed.
I have the following views for these pages:
def get_common_queryset():
usage_queryset = Usage.objects.all()
sub_usage_queryset = SubUsage.objects.all()
main_model_queryset = MainModel.objects.all()
pump_type_queryset = PumpType.objects.all()
queryset_dictionary = {
"usage_queryset": usage_queryset,
"sub_usage_queryset": sub_usage_queryset,
"main_model_queryset": main_model_queryset,
"pump_type_queryset": pump_type_queryset,
}
return queryset_dictionary
def products_usage_main(request):
queryset_dictionary = get_common_queryset()
context = queryset_dictionary
return render(request, "products/products_usage_main.html", context)
def products_model_main(request):
queryset_dictionary = get_common_queryset()
context = queryset_dictionary
return render(request, "products/products_model_main.html", context)
Here we have a get_common_queryset() function, which you can read about the reason of it in this question. Then we have two simillar view functions, products_usage_main and product_model_main but with different templates.
In the urls.py I have following paths for these views:
urlpatterns = [
path("application/", products_usage_main, name="products_usage_main"),
path("model/", products_model_main, name="products_model_main"),
]
In which, again, we can see that the two paths are similar with just different views.
And finally I have two separate templates for these two views, which their code is not needed or related to the problem I'm facing.
THE PROBLEM:
In my products page sidebar, I have two main links referencing /products/application/ and /products/model/, and when I click on the /products/application/, everything works just fine; but when /products/model/ is clicked, I get the following error:
ValidationError at /products/model/
['“model” is not a valid UUID.']
And when I looked into the traceback error, It said that the problem raised from product_detail view and in line product = Product.objects.get(id=pk), which has NOTHING to do with these two pages and their views!
Below is my product_detail view:
def product_detail(request, pk):
product = Product.objects.get(id=pk)
head_flow_dataset = HeadFlowDataSet.objects.filter(
product=product
).order_by("flow")
context_of_view = {
"product": product,
"head_flow_dataset_x": [],
"head_flow_dataset_y": [],
}
for head_flow in head_flow_dataset:
context_of_view["head_flow_dataset_x"].append(head_flow.flow)
context_of_view["head_flow_dataset_y"].append(head_flow.head)
queryset_dictionary = get_common_queryset()
context = {
**context_of_view,
**queryset_dictionary,
}
return render(request, "products/product_detail.html", context)
Below I'm sending complete error traceback in case you need it:
Internal Server Error: /products/model/
Traceback (most recent call last):
File "D:\Projects\Navid Motor\Website\Django\NavidMotor.com\.venv\lib\site-packages\django\db\models\fields\__init__.py", line 2649, in to_python
return uuid.UUID(**{input_form: value})
File "C:\Users\Vahid Moradi\AppData\Local\Programs\Python\Python310\lib\uuid.py", line 177, in __init__
raise ValueError('badly formed hexadecimal UUID string')
ValueError: badly formed hexadecimal UUID string
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "D:\Projects\Navid Motor\Website\Django\NavidMotor.com\.venv\lib\site-packages\django\core\handlers\exception.py", line 55, in inner
response = get_response(request)
File "D:\Projects\Navid Motor\Website\Django\NavidMotor.com\.venv\lib\site-packages\django\core\handlers\base.py", line 197, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "D:\Projects\Navid Motor\Website\Django\NavidMotor.com\products\views.py", line 152, in product_detail
product = Product.objects.get(id=pk)
File "D:\Projects\Navid Motor\Website\Django\NavidMotor.com\.venv\lib\site-packages\django\db\models\manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "D:\Projects\Navid Motor\Website\Django\NavidMotor.com\.venv\lib\site-packages\django\db\models\query.py", line 636, in get
clone = self._chain() if self.query.combinator else self.filter(*args, **kwargs)
File "D:\Projects\Navid Motor\Website\Django\NavidMotor.com\.venv\lib\site-packages\django\db\models\query.py", line 1420, in filter
return self._filter_or_exclude(False, args, kwargs)
File "D:\Projects\Navid Motor\Website\Django\NavidMotor.com\.venv\lib\site-packages\django\db\models\query.py", line 1438, in _filter_or_exclude
clone._filter_or_exclude_inplace(negate, args, kwargs)
File "D:\Projects\Navid Motor\Website\Django\NavidMotor.com\.venv\lib\site-packages\django\db\models\query.py", line 1445, in _filter_or_exclude_inplace
self._query.add_q(Q(*args, **kwargs))
File "D:\Projects\Navid Motor\Website\Django\NavidMotor.com\.venv\lib\site-packages\django\db\models\sql\query.py", line 1532, in add_q
clause, _ = self._add_q(q_object, self.used_aliases)
File "D:\Projects\Navid Motor\Website\Django\NavidMotor.com\.venv\lib\site-packages\django\db\models\sql\query.py", line 1562, in _add_q
child_clause, needed_inner = self.build_filter(
File "D:\Projects\Navid Motor\Website\Django\NavidMotor.com\.venv\lib\site-packages\django\db\models\sql\query.py", line 1478, in build_filter
condition = self.build_lookup(lookups, col, value)
File "D:\Projects\Navid Motor\Website\Django\NavidMotor.com\.venv\lib\site-packages\django\db\models\sql\query.py", line 1303, in build_lookup
lookup = lookup_class(lhs, rhs)
File "D:\Projects\Navid Motor\Website\Django\NavidMotor.com\.venv\lib\site-packages\django\db\models\lookups.py", line 27, in __init__
self.rhs = self.get_prep_lookup()
File "D:\Projects\Navid Motor\Website\Django\NavidMotor.com\.venv\lib\site-packages\django\db\models\lookups.py", line 341, in get_prep_lookup
return super().get_prep_lookup()
File "D:\Projects\Navid Motor\Website\Django\NavidMotor.com\.venv\lib\site-packages\django\db\models\lookups.py", line 85, in get_prep_lookup
return self.lhs.output_field.get_prep_value(self.rhs)
File "D:\Projects\Navid Motor\Website\Django\NavidMotor.com\.venv\lib\site-packages\django\db\models\fields\__init__.py", line 2633, in get_prep_value
return self.to_python(value)
File "D:\Projects\Navid Motor\Website\Django\NavidMotor.com\.venv\lib\site-packages\django\db\models\fields\__init__.py", line 2651, in to_python
raise exceptions.ValidationError(
django.core.exceptions.ValidationError: ['“model” is not a valid UUID.']
[12/Dec/2022 11:22:53] "GET /products/model/ HTTP/1.1" 500 145337
Inorder to solve this problem, I reviewed my other views, specially the product_detail view, and I tried to understand why this view should be the source of this problem.
In my products/urls.py I had a path to product_detail view, which was as below:
path("<str:pk>/", product_detail, name="product_detail"),
On the other hand model page url, as mentioned above, was as below:
path("model/", products_model_main, name="products_model_main"),
So I guess that the simillarities between these two paths was the source of the problem, and when I changed path url of product_detal to path("product-detail/<str:pk>/, both pages worked just fine.
UPDATE:
I found another solution and the main reason for this problem. After changing the product_detail path as mentioned above, it got me thinking about the reason for this problem, because, other than products/model/ I had another url with this structure, products/application/; so, why this problem only occured on model page? Then I checked my urls.py file throughly, and this was full paths in products.urls:
path("application/", products_usage_main, name="products_usage_main"),
path("<str:pk>/", product_detail, name="product_detail"),
path(
"application/single-application/<str:pk>",
products_single_usage_list,
name="products_single_usage_list",
),
path("model/", products_model_main, name="products_model_main"),
path(
"application/single-application/sub-application/<str:pk>",
products_sub_usage_list,
name="products_sub_usage_list",
),
path(
"model/single-model/<str:pk>",
products_single_model_list,
name="products_single_model_list",
),
path(
"model/single-model/pump-type/<str:pk>",
products_single_type_list,
name="products_single_type_list",
),
]
As you can see the order of the urls, first url is products/application/ and the second one is products/<str:pk>; I think Django checks the urls in this order, and it expects the model in products/model/ to be the <str:pk> part in the second url. So, I changed the order of urls, and it just worked fine without any need to change the product_detail page url.
Final urls.py code:
urlpatterns = [
path("application/", products_usage_main, name="products_usage_main"),
path("model/", products_model_main, name="products_model_main"),
path("<str:pk>/", product_detail, name="product_detail"),
path(
"application/single-application/<str:pk>",
products_single_usage_list,
name="products_single_usage_list",
),
path(
"application/single-application/sub-application/<str:pk>",
products_sub_usage_list,
name="products_sub_usage_list",
),
path(
"model/single-model/<str:pk>",
products_single_model_list,
name="products_single_model_list",
),
path(
"model/single-model/pump-type/<str:pk>",
products_single_type_list,
name="products_single_type_list",
),
]
I hope this answer would be helpfull for others who might encounter a problem like this.

Django Swagger starts failing when include is used in django urls

I am using django rest_framework_swagger for my django project, everything was working fine but when I added some URLs with include method Swagger start giving me 500 internal server error.
I am not sure why this error is coming, I have checked but didn't find anything to fix this error.
I am using:
django 1.11.7
rest_framework_swagger 2.1.2
django rest framework 3.7.3
URLs
from django.conf.urls import url, include
from link_one.views import LinkOneViewSet
from link_two.views import LinkTwoViewSet
schema_view = get_swagger_view(title='My Project APIs')
urlpatterns = [
url(r'^$', schema_view),
url(r'^foo/(?P<foo_id>\w+)/bar/(?P<bar_id>\w+)/link1',
LinkOneViewSet.as_view({'get': 'list'})),
url(r'^foo/(?P<foo_id>\w+)/bar/(?P<bar_id>\w+)/link2',
LinkTwoViewSet.as_view({'get': 'list'})),
url(r'^foo/(?P<foo_id>\w+)/bar/(?P<bar_id>\w+)/link3',
include('link_three.urls'))
]+ static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
Error
[25/Jan/2021 14:03:31] ERROR [django.request.exception:135] Internal Server Error: /
Traceback (most recent call last):
File "C:\Users\myuser\conda_env\lib\site-packages\django\core\handlers\exception.py", line 41, in inner
response = get_response(request)
File "C:\Users\myuser\conda_env\lib\site-packages\django\core\handlers\base.py", line 187, in _get_response
response = self.process_exception_by_middleware(e, request)
File "C:\Users\myuser\conda_env\lib\site-packages\django\core\handlers\base.py", line 185, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\myuser\conda_env\lib\site-packages\django\views\decorators\csrf.py", line 58, in wrapped_view
return view_func(*args, **kwargs)
File "C:\Users\myuser\conda_env\lib\site-packages\django\views\generic\base.py", line 68, in view
return self.dispatch(request, *args, **kwargs)
File "C:\Users\myuser\conda_env\lib\site-packages\rest_framework\views.py", line 489, in dispatch
response = self.handle_exception(exc)
File "C:\Users\myuser\conda_env\lib\site-packages\rest_framework\views.py", line 449, in handle_exception
self.raise_uncaught_exception(exc)
File "C:\Users\myuser\conda_env\lib\site-packages\rest_framework\views.py", line 486, in dispatch
response = handler(request, *args, **kwargs)
File "C:\Users\myuser\conda_env\lib\site-packages\rest_framework_swagger\views.py", line 32, in get
schema = generator.get_schema(request=request)
File "C:\Users\myuser\conda_env\lib\site-packages\rest_framework\schemas\generators.py", line 278, in get_schema
links = self.get_links(None if public else request)
File "C:\Users\myuser\conda_env\lib\site-packages\rest_framework\schemas\generators.py", line 316, in get_links
link = view.schema.get_link(path, method, base_url=self.url)
File "C:\Users\myuser\conda_env\lib\site-packages\rest_framework\schemas\inspectors.py", line 179, in get_link
fields += self.get_serializer_fields(path, method)
File "C:\Users\myuser\conda_env\lib\site-packages\rest_framework\schemas\inspectors.py", line 302, in get_serializer_fields
serializer = view.get_serializer()
File "C:\Users\myuser\conda_env\lib\site-packages\rest_framework\generics.py", line 112, in get_serializer
return serializer_class(*args, **kwargs)
TypeError: 'list' object is not callable
After searching a lot and debugging, I have found a solution for this.
The solution is, don't use multiple serializer classes for a ViewSet.
In my one viewset I was doing this and this is what creating the problem.
class FooBarViewset(ModelViewSet):
serializer_class = [DefaultSerializer, BarSerializer, FooSerializer]
But I did not realize that this will cause the error.
Here is Fix that I am using
class FooBarViewset(ModelViewSet):
serializer_class = DefaultSerializer
You can also use the get_serializer method and map serializer class with an action, please check this answer Django rest framework, use different serializers in the same ModelViewSet

I am getting the error below every time I run the code and I do not know what is wrong

I am getting the error below. Any help is appreciated. I am probably missing something very important from the documentation.
Kindly point out my mistake if you see it and enlighten me about many to many relations from Django. From the error presented does it mean that the .add() function cannot be used on querysets?
Traceback
Internal Server Error: /7/
Traceback (most recent call last):
File "C:\Users\hanya\AppData\Local\Programs\Python\Python37\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
response = get_response(request)
File "C:\Users\hanya\AppData\Local\Programs\Python\Python37\lib\site-packages\django\core\handlers\base.py", line 126, in _get_response
response = self.process_exception_by_middleware(e, request)
File "C:\Users\hanya\AppData\Local\Programs\Python\Python37\lib\site-packages\django\core\handlers\base.py", line 124, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\music\songs\views.py", line 141, in Playlist_Add
playlist.song.add(song)
File "C:\Users\hanya\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\models\fields\related_descriptors.py", line 926, in add
self._add_items(self.source_field_name, self.target_field_name, *objs)
File "C:\Users\hanya\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\models\fields\related_descriptors.py", line 1073, in _add_items
'%s__in' % target_field_name: new_ids,
File "C:\Users\hanya\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\models\query.py", line 844, in filter
return self._filter_or_exclude(False, *args, **kwargs)
File "C:\Users\hanya\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\models\query.py", line 862, in _filter_or_exclude
clone.query.add_q(Q(*args, **kwargs))
File "C:\Users\hanya\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\models\sql\query.py", line 1263, in add_q
clause, _ = self._add_q(q_object, self.used_aliases)
File "C:\Users\hanya\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\models\sql\query.py", line 1287, in _add_q
split_subq=split_subq,
File "C:\Users\hanya\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\models\sql\query.py", line 1225, in build_filter
condition = self.build_lookup(lookups, col, value)
File "C:\Users\hanya\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\models\sql\query.py", line 1096, in build_lookup
lookup = lookup_class(lhs, rhs)
File "C:\Users\hanya\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\models\lookups.py", line 20, in __init__
self.rhs = self.get_prep_lookup()
File "C:\Users\hanya\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\models\fields\related_lookups.py", line 59, in get_prep_lookup
self.rhs = [target_field.get_prep_value(v) for v in self.rhs]
File "C:\Users\hanya\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\models\fields\related_lookups.py", line 59, in <listcomp>
self.rhs = [target_field.get_prep_value(v) for v in self.rhs]
File "C:\Users\hanya\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\models\fields\__init__.py", line 965, in get_prep_value
return int(value)
TypeError: int() argument must be a string, a bytes-like object or a number, not 'QuerySet'
[16/Apr/2020 23:06:55] "GET /7/ HTTP/1.1" 500 127314
models.py
class Playlist (models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, default=1)
song = models.ManyToManyField(Song)
views.py
def Playlist_Add(request, id):
song = Song.objects.filter(id=id)
playlist, created = Playlist.objects.get_or_create(user=request.user)
#playlist.save()
playlist.song.add(song)
return redirect('home:home')
urls.py
path('<int:id>/', views.Playlist_Add, name='playlist_add'),
templates
<footer class="w3-container w3-blue">
<a href="{% url 'playlist_add' id=obj.id %}">
<button type="button" class="btn btn-info">+ To Playlist</button>
</a>
<h5>last edited:&nbsp {{objects.timestamp}}</h5>
</footer>
Your song is not a single song, it is a QuerySet of songs, it thus can contain zero, one or more songs. Because you filter on a primary key, it can only contain zero or one Songs, but regardless, it is still a collection.
You can fix this by using a .get(..) over a .filter(), or better, a get_object_or_404(..):
from django.shortcuts import get_object_or_404
def Playlist_Add(request, id):
song = get_object_or_404(Song, id=id)
playlist, created = Playlist.objects.get_or_create(user=request.user)
#playlist.save()
playlist.song.add(song)
return redirect('home:home')
Note: A GET request is not supposed to have side-effects, hence constructing
objects when a user makes a GET request, is not compliant with the HTTP
standard. Therefore it might be better to turn this into a POST request.

django - Unsupported lookup for JSONField or join on the field not permitted

I am having a Json field in my models as -
class Product(models.Model):
...
detailed_stock = JSONField(load_kwargs={'object_pairs_hook': collections.OrderedDict},default=dict)
I am having values in my database like -
{
"total":0,
"5[1]":0
}
I am trying to filter objects with total = 0, for that I tried -
Product.objects.filter(detailed_stock__total = 0)
but it throws error -
Unsupported lookup 'total' for JSONField or join on the field not permitted.
as per the documentation the following code is permitted.
this is full traceback-
Traceback (most recent call last):
File "C:\Users\lenovo\AppData\Local\conda\conda\envs\myDjangoEnv\lib\site-packages\django\core\handlers\exception.py", line 35, in inner
response = get_response(request)
File "C:\Users\lenovo\AppData\Local\conda\conda\envs\myDjangoEnv\lib\site-packages\django\core\handlers\base.py", line 128, in _get_response
response = self.process_exception_by_middleware(e, request)
File "C:\Users\lenovo\AppData\Local\conda\conda\envs\myDjangoEnv\lib\site-packages\django\core\handlers\base.py", line 126, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\lenovo\AppData\Local\conda\conda\envs\myDjangoEnv\lib\site-packages\django\views\generic\base.py", line 69, in view
return self.dispatch(request, *args, **kwargs)
File "C:\Users\lenovo\AppData\Local\conda\conda\envs\myDjangoEnv\lib\site-packages\braces\views\_access.py", line 102, in dispatch
request, *args, **kwargs)
File "C:\Users\lenovo\AppData\Local\conda\conda\envs\myDjangoEnv\lib\site-packages\django\views\generic\base.py", line 89, in dispatch
return handler(request, *args, **kwargs)
File "C:\Users\lenovo\AppData\Local\conda\conda\envs\myDjangoEnv\lib\site-packages\django\views\generic\list.py", line 142, in get
self.object_list = self.get_queryset()
File "c:\Users\lenovo\Desktop\My_Django_Stuff\bekaim\accounts\views.py", line 142, in get_queryset
queryset = Product.objects.filter(detailed_stock__total = 0)
File "C:\Users\lenovo\AppData\Local\conda\conda\envs\myDjangoEnv\lib\site-packages\django\db\models\query.py", line 836, in filter
return self._filter_or_exclude(False, *args, **kwargs)
File "C:\Users\lenovo\AppData\Local\conda\conda\envs\myDjangoEnv\lib\site-packages\django\db\models\query.py", line 854, in _filter_or_exclude
clone.query.add_q(Q(*args, **kwargs))
File "C:\Users\lenovo\AppData\Local\conda\conda\envs\myDjangoEnv\lib\site-packages\django\db\models\sql\query.py", line 1253, in add_q
clause, _ = self._add_q(q_object, self.used_aliases)
File "C:\Users\lenovo\AppData\Local\conda\conda\envs\myDjangoEnv\lib\site-packages\django\db\models\sql\query.py", line 1271, in _add_q
current_negated, allow_joins, split_subq)
File "C:\Users\lenovo\AppData\Local\conda\conda\envs\myDjangoEnv\lib\site-packages\django\db\models\sql\query.py", line 1277, in _add_q
split_subq=split_subq,
File "C:\Users\lenovo\AppData\Local\conda\conda\envs\myDjangoEnv\lib\site-packages\django\db\models\sql\query.py", line 1215, in build_filter
condition = self.build_lookup(lookups, col, value)
File "C:\Users\lenovo\AppData\Local\conda\conda\envs\myDjangoEnv\lib\site-packages\django\db\models\sql\query.py", line 1069, in build_lookup
lhs = self.try_transform(lhs, name)
File "C:\Users\lenovo\AppData\Local\conda\conda\envs\myDjangoEnv\lib\site-packages\django\db\models\sql\query.py", line 1115, in try_transform
(name, lhs.output_field.__class__.__name__))
django.core.exceptions.FieldError: Unsupported lookup 'total' for JSONField or join on the field not permitted.
[31/Dec/2018 16:13:37] "GET /accounts/product-list/?clean=outofstock HTTP/1.1" 500 150927
I searched on internet but unable to find the solution, please help.
I think you are using django-jsonfield as indicated by load_kwargs={'object_pairs_hook': collections.OrderedDict} instead of django.contrib.postgres.fields.JSONField.
django-jsonfield is for databases which don't offer a native dict type and is based on a simple TextField. When you access the field value using product.detail_stock the internally saved str is converted to dict using json.loads() by the field itself. Hence you can only use operations like icontains and contains for querying that field.
If you are using postgres as a database, you are able to take full advantage of django.contrib.postgres.fields.JSONField as the documentation states. But you have to import the correct JSONfield by using django.contrib.postgres.fields import JSONField.
There is a solution for mysql (package django-mysql) too.
If you are using Django and have used:
from json_field import JSONField
Then you can not benefit the SQL lookup. As mentioned above, JSONField overrides the
TextField only. It validates the JSONformat and dumps as string.
class JSONField(models.TextField):
""" Stores and loads valid JSON objects. """
Instead use
from django.db import models
data = models.JSONField(null=True)

DRF How to optimize this query, instead of looping if's?

I have a query in mind, currently it works as expected in shell with the Django ORM:
>>> Place.objects.all()[0].images.filter(order=0)[0].filename
'y5IUMPyv.jpg'
But I don't know how to implement it with DRF's SerializerMethodField. This is what I'm using in the meantime until I can figure it out:
class CardSerializer(serializers.Serializer):
image = serializers.SerializerMethodField()
#staticmethod
def get_image(obj):
for d in obj.images.all():
if d.order == 0:
return d.filename
This is the "ideal" method that doesn't work, and I don't know why:
#staticmethod
def get_image(obj):
return obj.images.filter(order=0)[0].filename
Traceback (most recent call last):
File "/home/admin/env/lib/python3.4/site-packages/django/core/handlers/base.py", line 149, in get_response
response = self.process_exception_by_middleware(e, request)
File "/home/admin/env/lib/python3.4/site-packages/django/core/handlers/base.py", line 147, in get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/admin/env/lib/python3.4/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view
return view_func(*args, **kwargs)
File "/home/admin/env/lib/python3.4/site-packages/django/views/generic/base.py", line 68, in view
return self.dispatch(request, *args, **kwargs)
File "/home/admin/env/lib/python3.4/site-packages/rest_framework/views.py", line 466, in dispatch
response = self.handle_exception(exc)
File "/home/admin/env/lib/python3.4/site-packages/rest_framework/views.py", line 463, in dispatch
response = handler(request, *args, **kwargs)
File "/home/admin/env/lib/python3.4/site-packages/rest_framework/generics.py", line 201, in get
return self.list(request, *args, **kwargs)
File "/home/admin/env/lib/python3.4/site-packages/rest_framework/mixins.py", line 45, in list
return self.get_paginated_response(serializer.data)
File "/home/admin/env/lib/python3.4/site-packages/serpy/serializer.py", line 134, in data
self._data = self.to_value(self.instance)
File "/home/admin/env/lib/python3.4/site-packages/serpy/serializer.py", line 123, in to_value
return [serialize(o, fields) for o in instance]
File "/home/admin/env/lib/python3.4/site-packages/serpy/serializer.py", line 123, in <listcomp>
return [serialize(o, fields) for o in instance]
File "/home/admin/env/lib/python3.4/site-packages/serpy/serializer.py", line 107, in _serialize
result = getter(self, instance)
File "/home/admin/src/places/serializers.py", line 72, in get_image
return obj.images.filter(order=0)[0].filename
File "/home/admin/env/lib/python3.4/site-packages/django/db/models/query.py", line 297, in __getitem__
return list(qs)[0]
IndexError: list index out of range
As the iron maiden #anderson-lima has pointed out, this is a problem with your data rather than your code. You do not have an image with order = 0 and your first method handles that situation correct if not optimally.
#staticmethod
def get_image(obj):
for d in obj.images.all():
if d.order == 0:
return d.filename
# returns None here if an object with order = 0
# does not exist in the database.
However in your second approach you are taking a slice but fetching an object that does not exist. Hence the execption, and which in turn tells us that what you need is a just a try except block.
#staticmethod
def get_image(obj):
try:
return obj.images.filter(order=0)[0].filename
except IndexError:
return None