2

My IDE (PyCharm) keeps reporting: Function-based generic views have been deprecated.

I have the following statement in my import list:

from django.views.generic.list_detail import object_list

And my view looks like the following:

def category(request, id, slug=None):
    category = Category.objects.get(pk=id)

    books = Book.objects.filter(
        Q(status = 1) & Q(category=category)
    ).order_by('-id')

    s = Poet.objects.order_by('?')[:3]

    return object_list(
        request,
        template_name = 'books/categories/show.html',
        queryset = books,
        paginate_by = 99,
        extra_context = {
            'category': category,
            'suggestions': s,
            'bucket_name': config.BOOKS_BUCKET_NAME,
            }
    )

I found this in SO, but the docs seems overly complicated in this regard.

Any tips on how I can convert my code would be appreciated.

Community
  • 1
  • 1
Adam
  • 2,948
  • 10
  • 43
  • 74

1 Answers1

2

You could try something like this

from django.views.generic import ListView

class CategoryView(ListView):
    template_name = 'books/categories/show.html'
    paginate_by = 99

    def get_queryset(self):
        self.category = Category.objects.get(pk=self.kwargs['id'])

        books = Book.objects.filter(
           Q(status = 1) & Q(category=self.category)
        ).order_by('-id')

        self.s = Poet.objects.order_by('?')[:3]

        return books

    def get_context_data(self, **kwargs):
        context = super(CategoryView, self).get_context_data(**kwargs)
        context['category'] = self.category
        context['suggestions'] = self.s
        return context

This code is not tested, please report back if it's working for you. Note that the book list will be available through the context variable 'object_list', if you want to give it a different name you can use the 'context_object_name' class member:

class CategoryView(ListView):
    template_name = 'books/categories/show.html'
    context_object_name = 'books'
    ...

and in your urls.py use the class-based view's as_view() method

url( r'your pattern', CategoryView.as_view(), name='whatever')
ppetrid
  • 3,745
  • 27
  • 29
  • Thanks that almost worked except I have a custom pagination: {% if is_paginated %}{% load paginator %}{% paginator 3 %}{% endif %}... and on paginator.py custom template tag I have def paginator(context, adjacent_pages=2, is_random=False): and the first line of this function is startPage = max(context['page'] - adjacent_pages, 1). It's giving the following error: Exception Type: KeyError Exception Value: 'page'. What's wrong? – Adam Dec 27 '12 at 04:06
  • 1
    try to use max(context['page_obj']).. instead of max(context['page']) and see how it goes – ppetrid Dec 27 '12 at 04:14
  • I got: unsupported operand type(s) for -: 'Page' and 'int'. Here's my code: http://bpaste.net/show/Puu0jMqkGcUqy1N9vXwH/ – Adam Dec 27 '12 at 04:26
  • 1
    Sorry my mistake, you must use context['page_obj'].number to get the page number. You can also see this question http://stackoverflow.com/questions/5907575/how-do-i-use-pagination-with-django-class-based-generic-listviews and the docs for the new pagination Page class (which you have in your context['page_obj'] variable) https://docs.djangoproject.com/en/dev/topics/pagination/?from=olddocs#django.core.paginator.Page – ppetrid Dec 27 '12 at 04:31