Come migrare dalle viste generiche basate su funzioni alle analoghe basate su classi in Django

La settimana scorsa ho migrato un’applicazione Django dalla versione 1.04 alla versione 1.6.

Tra gli innumerevoli metodi deprecati, dalla versione 1.5 di Django sono state eliminate le viste generiche basate su funzioni, già deprecate nella versione precedente (https://docs.djangoproject.com/en/1.4/topics/generic-views-migration/).

Nella mia applicazione, la vista generica veniva utilizzata nel file views.py, in questo modo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

@cache_page()
from django.views.generic.list_detail import object_list

def user_comments(request, username):
try:
user = User.objects.get(username=username)
except User.DoesNotExist:
raise Http404

comments = Comment.objects.filter(user=user).order_by('-submit_date')
return object_list(request,
queryset=comments,
template_name="infosite/comments_user.html",
template_object_name="comments",
extra_context={'comments_count':comments.count()},
paginate_by=5,
allow_empty=True,
)

Come si puo’ notare, il nostro metodo nella view creava una lista generica di commenti, aggiungendo inoltre un extra context.

Durante la migrazione alla versione 1.6 del framework ho dovuto fronteggiare due problematiche:

- la migrazione delle generic view da funzioni a classi
- l’impossibilità di aggiungere un extra_context nella relativa ListView.

Per prima cosa ho dunque esteso la ListView per poter aggiungere il parametro aggiuntivo extra_context:

1
2
3
4
5
6
7
8

from django.views.generic import ListView

class SubListView(ListView):
extra_context = {}
def get_context_data(self, **kwargs):
context = super(SubListView, self).get_context_data(**kwargs)
context.update(self.extra_context)
return context

Infine, ho modificato la mia view come di seguito:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

@cache_page(CACHE_MIDDLEWARE_SECONDS)
def user_comments(request, username):

try:
user = User.objects.get(username=username)
except User.DoesNotExist:
raise Http404

comments = Comment.objects.filter(user=user).order_by('-submit_date')
callable = SubListView.as_view( queryset=comments,
template_name="infosite/comments_user.html",
template_object_name="comments",
extra_context={'comments_count':comments.count()},
paginate_by=5,
allow_empty=True,
)
return callable(request)

Che ne pensate di questa soluzione?