如何将基于函数的视图转换为基于类的视图

时间:2019-05-24 09:33:10

标签: python django django-views

我有一个基于函数的视图,我试图将其转换为基于类的视图(DetailView)。基于函数的视图等效于CBV中的DetailView。我该怎么办?

这是基于功能的视图

def show_post(request, post):
    """A View to display a single post.
    The post variable here is the slug to a post.
    The slug to a post may possibly be a duplicate. So we filter all posts by 
    the slug (which is the 1st variable here)
    And then select the first post returned by the filter queryset.
    The first post returned is, of course, the post we are trying to view.
    """
    post = Post.objects.filter(slug=post)
    if post.exists():
        post = post[0]
    else:
        return HttpResponseRedirect('/blog/')
     count_visits = None
    unique_views = set()

    if request.user.is_authenticated:
        post_views = PostView.objects.filter(post=post)
        count_visits = post_views.count()
        for post_view in post_views:
            unique_views.add(post_view.ip)
    else:
        post_view = PostView(post=post, ip=request.META.get('REMOTE_ADDR',''),
                      http_host=request.META.get('HTTP_HOST', ''),
                      http_referrer=request.META.get('HTTP_REFERER',''),                    
                      http_user_agent=request.META.get('HTTP_USER_AGENT', ''),
                             remote_host=request.META.get('REMOTE_HOST', ''))
        post_view.save()

    c = {
        'post': post,
        'comments': comments,
        'new_comment': new_comment,
        'similar_posts': similar_posts,
        'count_visits': count_visits,
        'unique_views': unique_views,
        'comments_count': comments_count,
        'message': message,
    }
    return render(request, 'blog/posts/post.html', c)

然后我尝试使用以下方法将其转换为基于类的视图:

class PostDetailView(DetailView):
    model = Post
    template_name = 'blog/post.html'
    context_object_name = 'post'

    def get_context_data(self, **kwargs):
        self.slug = get_object_or_404(Post, slug=self.kwargs['slug'])        
        p = Post.objects.filter(slug=self.slug).first()
        if p.exists():
            p = p[0]
        else:
            return HttpResponseRedirect('/blog/')
        count_visits = None
        unique_views = set()

        if self.request.user.is_authenticated:
            post_views = PostView.objects.filter(post=p)
            count_visits = post_views.count()
            for post_view in post_views:
                unique_views.add(post_view.ip)

        else:
            post_view = PostView(ip=self.request.META.get('REMOTE_ADDR', ''),
                 http_host=self.request.META.get('HTTP_HOST', ''),
                 http_referrer=self.request.META.get('HTTP_REFERER', ''),                               
                 http_user_agent=self.request.META.get('HTTP_USER_AGENT', ''),                                 
                 remote_host=self.request.META.get('REMOTE_HOST', ''))

            post_view.save()

        c = {
            'count_visits': count_visits,
            'unique_views': unique_views,
        }

        return render(self.request, self.template_name, c)

我不确定这是否是正确的方法。请帮助我。

非常感谢。

1 个答案:

答案 0 :(得分:2)

默认情况下,DetailView应该处理传递到您的url上的pk / slug,因此您不需要在{{1}内的前两行进行查询集}。相信一种更清晰的方法是这样的:

get_context_data