When moving my blog from WordPress to Django I changed the structure of the permalinks, before it was not used category
in the structure and now it is. More or less so:
/slug/ ⟼ /cat/slug/
And so I'm getting a lot of 404 errors, because Django only searches on category. So I decided to add a finder in the class-based view of the categories:
class CategoryDetail(ListView, CacheMixin):
model = Entry
paginate_by = 6
def get_queryset(self):
self.cat = get_object_or_404(Category, slug=self.kwargs['slug'])
return Entry.objects.filter(
category=self.cat, status=Entry.LIVE_STATUS).select_related() \
.order_by('-pub_date', 'id')
In the function get_queryset
I want to add a redirect that calls the class EntryDetail
if the slug
corresponds to an entry and not a category.
I do it like this:
def get_queryset(self):
try:
entry = Entry.objects.get(slug=self.kwargs['slug'])
return redirect(entry)
except Entry.DoesNotExist:
pass
self.cat = get_object_or_404(Category, slug=self.kwargs['slug'])
return Entry.objects.filter(
category=self.cat, status=Entry.LIVE_STATUS).select_related() \
.order_by('-pub_date', 'id')
I use the slug
to search for the input (if it doesn't find it , I catch the exception DoesNotExist
and go on to find the category) and if that entry exists, I redirect the request to the indicated input, which contains the property get_absolute_url()
as indicated in the documentation with return redirect(entry)
. But it does not work.
It also doesn't work if I use this form of redirect
, which matches the URL pattern:
# En urls.py:
# url(r'^(?P<cat>[-\w]+)/(?P<slug>[-\w]+)/$', EntryDetail.as_view(), name="entry_detail")
return redirect('entry_detail', cat=entry.category, slug=entry.slug)
The problem, in both cases, is that I get the following error:
TypeError at /el-circulo/
object of type 'HttpResponseRedirect' has no len()
The function len()
is used for paging, because I keep sending the response to the CBV CategoryDetail
.
How can I get the wording I need to work?
That is, how can I leave the class that was called by the request and return the response with a different class, in this case with EntryDetail
.
I imagine the error:
It happens because you are returning a
HttpResponseRedirect
instead of a queryset which is what the method should returnget_queryset
. As I mentioned in my comment, I don't think this method is the right place for a redirect.What I would do is pass the redirection to the method
get
and leave the queryset part as you had it initially: