My Problem
I have a queryset in Django View. That queryset should return an instance. But instead of that it returns a value
Models.py
class Author(models.Model):
name = models.CharField(max_length=250, unique=True)
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('authors:author_detail', args=[str(self.id)])
class Meta:
verbose_name = 'Author'
verbose_name_plural = 'Authors'
Projects URLS.py
urlpatterns = [
path('admin/', admin.site.urls),
path('author/', include('authors_app.urls', namespace='authors')),
]
authors_app ULRS.py
from .views import *
app_name = 'authors'
urlpatterns = [
path('<int:pk>/', AuthorDetail.as_view(), name='author_detail'),
]
Views.py
class AuthorDetail(ListView):
model = Book
context_object_name = 'author_books'
template_name = 'author-detail.html'
queryset = Book.objects.all().order_by('bookinfo__bestseller')
paginate_by = 36
def get_queryset(self, **kwargs):
author_id = Author.objects.get(pk = self.kwargs['pk'])
print(author_id)
qs = super().get_queryset(**kwargs)
return qs.filter(author = author_id)
def get_context_data(self, **kwargs):
# Call the base implementation first to get a context
context = super().get_context_data(**kwargs)
# Add in a QuerySet
context['author'] = Author.objects.get(pk = self.kwargs['pk'])
# context['image'] = f"/mnt/HDD/wiki/parser/images/photos/10.png"
return context
Traceback
Traceback (most recent call last):
File "/mnt/HDD/tibrains.test/titest-env/lib/python3.8/site-packages/django/core/handlers/exception.py", line 47, in inner
response = get_response(request)
File "/mnt/HDD/tibrains.test/titest-env/lib/python3.8/site-packages/django/core/handlers/base.py", line 181, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/mnt/HDD/tibrains.test/titest-env/lib/python3.8/site-packages/django/views/generic/base.py", line 70, in view
return self.dispatch(request, *args, **kwargs)
File "/mnt/HDD/tibrains.test/titest-env/lib/python3.8/site-packages/django/views/generic/base.py", line 98, in dispatch
return handler(request, *args, **kwargs)
File "/mnt/HDD/tibrains.test/titest-env/lib/python3.8/site-packages/django/views/generic/list.py", line 142, in get
self.object_list = self.get_queryset()
File "/mnt/HDD/tibrains/08/titest_project/authors_app/views.py", line 17, in get_queryset
return qs.filter(author = author_id)
File "/mnt/HDD/tibrains.test/titest-env/lib/python3.8/site-packages/django/db/models/query.py", line 941, in filter
return self._filter_or_exclude(False, args, kwargs)
File "/mnt/HDD/tibrains.test/titest-env/lib/python3.8/site-packages/django/db/models/query.py", line 961, in _filter_or_exclude
clone._filter_or_exclude_inplace(negate, args, kwargs)
File "/mnt/HDD/tibrains.test/titest-env/lib/python3.8/site-packages/django/db/models/query.py", line 968, in _filter_or_exclude_inplace
self._query.add_q(Q(*args, **kwargs))
File "/mnt/HDD/tibrains.test/titest-env/lib/python3.8/site-packages/django/db/models/sql/query.py", line 1393, in add_q
clause, _ = self._add_q(q_object, self.used_aliases)
File "/mnt/HDD/tibrains.test/titest-env/lib/python3.8/site-packages/django/db/models/sql/query.py", line 1412, in _add_q
child_clause, needed_inner = self.build_filter(
File "/mnt/HDD/tibrains.test/titest-env/lib/python3.8/site-packages/django/db/models/sql/query.py", line 1320, in build_filter
self.check_related_objects(join_info.final_field, value, join_info.opts)
File "/mnt/HDD/tibrains.test/titest-env/lib/python3.8/site-packages/django/db/models/sql/query.py", line 1147, in check_related_objects
self.check_query_object_type(value, opts, field)
File "/mnt/HDD/tibrains.test/titest-env/lib/python3.8/site-packages/django/db/models/sql/query.py", line 1128, in check_query_object_type
raise ValueError(
ValueError: Cannot query "Lawrence Gilman": Must be "Author" instance.
When I open authors page - mysite.com/author/51/ I've got an Error: Cannot query "Lawrence Gilman": Must be "Author" instance.
Question
How can I get an instance in that queryset?
CodePudding user response:
I think this is the problem:
author_id = Author.objects.get(pk = self.kwargs['pk'])
use filter
instead of get
:
author_id = Author.objects.filter(pk = self.kwargs['pk'])
CodePudding user response:
You can filter with the author_id
itself, and thus obtain a get_queryset
with:
from django.shortcuts import get_object_or_404
class AuthorDetailView(ListView):
# …
def get_queryset(self, **kwargs):
return super().get_queryset(**kwargs).filter(author_id=self.kwargs['pk'])
def get_context_data(self, **kwargs):
return super().get_context_data(
**kwargs, author=get_object_or_404(Author, pk=self.kwargs['pk'])
)