我是CBV的初学者,可以寻求帮助来重构我的FBV。也许您可以向我展示一些示例或建议。如您所见,我对DRY原理也有疑问。
我的FBV:
def formen(request):
html = 'man_index.html'
ip, is_routable = get_client_ip(request)
if request.user.is_authenticated and request.user.sex == 'M':
queryset = Post.objects.filter(sex=request.user.sex, is_published=True)
query = request.GET.get('q')
if query:
queryset = queryset.filter(title__icontains=query)
paginator = Paginator(queryset, 6)
page = request.GET.get('page')
try:
elements = paginator.page(page)
except PageNotAnInteger:
elements = paginator.page(1)
except EmptyPage:
elements = paginator.page(paginator.num_pages)
elements = paginator.get_page(page)
context = {
'all_posts': elements,
'page_range' : paginator.page_range,
}
elif request.user.is_authenticated and request.user.sex == 'W':
return redirect('/forwomen')
else:
queryset = Post.objects.filter(sex='M', is_published=True)
query = request.GET.get('q')
if query:
queryset = queryset.filter(title__icontains=query)
paginator = Paginator(queryset, 3)
page = request.GET.get('page')
try:
elements = paginator.page(page)
except PageNotAnInteger:
elements = paginator.page(1)
except EmptyPage:
elements = paginator.page(paginator.num_pages)
elements = paginator.get_page(page)
context = {
'all_posts': elements,
'page_range' : paginator.page_range,
}
return render(request, html, context)
我应该使用什么方法将其重构为CVB?
答案 0 :(得分:2)
这看起来像一个列表视图,因此我们可以编写ListView
[django-doc]类的子类:
从django.views.generic.list导入ListView
class ForMenView(ListView):
model = Post
template_name = 'man_index.html'
context_object_name = 'all_posts'
paginate_by = 3
def get_queryset(self):
query = request.GET.get('q')
qs = Post.objects.filter(sex='M', is_published=True)
if query:
return qs.filter(title__icontains=query)
return qs
def get_paginate_by(self, queryset):
user = self.request.user
if user.is_authenticated and user.sex == 'M':
return 6
return self.paginate_by
def dispatch(self, request, *args, **kwargs):
user = request.user
if user.is_authenticated and user.sex == 'W':
return redirect('/forwomen') # please replace it with the view name
else:
return super(ArticleListView, self).dispatch(*args, **kwargs)
def get_context_data(self, *args, **kwargs):
kwargs = super(ArticleListView, self).get_context_data(*args, **kwargs)
kwargs['page_range'] = kwargs['paginator'].page_range
return kwargs
但是基于函数的视图显示了一些奇怪的东西:
paginator.page_range
作为单独的变量是很奇怪的,因为通过使用对分页器本身的引用,可以访问更多属性。使用这种基于类的视图并不能解决所有问题,因为我不知道/forwoman
等的详细信息。因此,您可以将其视为 advice 的重构方法