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

Python 如何将基于函数的视图转换为基于类的视图,python,django,django-views,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

我尝试将基于函数的视图转换为基于类的视图(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)
我不确定这样做是否正确。请帮助我

非常感谢。

默认情况下,A应该负责传递到url上的pk/slug,因此您不需要进行查询,只需在
获取上下文数据的前两行中进行查询。A我相信一种更清晰的方法会是这样:

class PostDetailView(详细视图):
型号=员额
模板名称='blog/post.html'
上下文\对象\名称='post'
def获取上下文数据(自身,**kwargs):
context=super()。获取上下文数据(**kwargs)
如果self.object为无:
返回HttpResponseRedirect(反向('blog'))
访问次数=无
唯一视图=集合()
如果self.request.user.u经过身份验证:
post\u views=PostView.objects.filter(post=self.object)
count_visions=post_views.count()
对于post_视图中的post_视图:
唯一视图。添加(post\u view.ip)
其他:
post_view=PostView.objects.create(
ip=self.request.META.get('REMOTE_ADDR',''),
http_host=self.request.META.get('http_host',''),
http_REFERER=self.request.META.get('http_REFERER',''),
http\u user\u agent=self.request.META.get('http\u user\u agent',''),
remote\u host=self.request.META.get('remote\u host','')
)
context.update({
“计数访问”:计数访问,
“唯一视图”:唯一视图,
})
返回上下文
默认情况下,A应该负责传递到url上的pk/slug,因此您不需要在
get\u context\u数据的前两行进行查询。A我相信一种更清晰的方法会是这样:

class PostDetailView(详细视图):
型号=员额
模板名称='blog/post.html'
上下文\对象\名称='post'
def获取上下文数据(自身,**kwargs):
context=super()。获取上下文数据(**kwargs)
如果self.object为无:
返回HttpResponseRedirect(反向('blog'))
访问次数=无
唯一视图=集合()
如果self.request.user.u经过身份验证:
post\u views=PostView.objects.filter(post=self.object)
count_visions=post_views.count()
对于post_视图中的post_视图:
唯一视图。添加(post\u view.ip)
其他:
post_view=PostView.objects.create(
ip=self.request.META.get('REMOTE_ADDR',''),
http_host=self.request.META.get('http_host',''),
http_REFERER=self.request.META.get('http_REFERER',''),
http\u user\u agent=self.request.META.get('http\u user\u agent',''),
remote\u host=self.request.META.get('remote\u host','')
)
context.update({
“计数访问”:计数访问,
“唯一视图”:唯一视图,
})
返回上下文

get\u context\u data
方法应返回
context
字典,但不返回响应实例。只需
返回c
获取上下文数据
方法应返回
上下文
字典,但不返回响应实例。只是为了
返回c
供参考,最好使用
反向
URL名称@Toluwalemi您可以将
return-HttpResponseRedirect('/blog/')
替换为
return-HttpResponseRedirect(反向('blog'))
如果url名称
博客
有模式
/blog/
。我希望你得到了理想的答案。谢谢@xxbinxx。我将编辑我的答案。只是不要忘记解释你所做的每一个更改,否则提问者将无法正确理解。仅供参考,对url使用
反向
名称是一种很好的做法。@Toluwalemi你可以替换它
return-HttpResponseRedirect('/blog/')
with
return-HttpResponseRedirect(reverse('blog'))
如果url名称
blog
有模式
/blog/
。我希望你得到了理想的答案。谢谢@xxbinxx。我将编辑我的答案。只是不要忘记解释你所做的每一个更改,否则提问者将无法正确理解。