Как преобразовать представления на основе функций в представления на основе классов - PullRequest
0 голосов
/ 24 мая 2019

У меня есть представление на основе функций, которое я пытаюсь преобразовать в представление на основе классов (DetailView).Представление на основе функций является эквивалентом DetailView в CBV.Как мне это сделать?

Это представление на основе функций

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 Ответ

2 голосов
/ 24 мая 2019

A DetailView по умолчанию должен позаботиться о pk / slug, передаваемом на ваш URL, поэтому вам не нужно выполнять набор запросов, который вы делаете в первых 2 строках внутри вашего get_context_data. Поверьте, более ясный способ сделать это будет выглядеть примерно так:

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

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        if self.object is None:
            return HttpResponseRedirect(reverse('blog'))

        count_visits = None
        unique_views = set()

        if self.request.user.is_authenticated:
            post_views = PostView.objects.filter(post=self.object)
            count_visits = post_views.count()
            for post_view in post_views:
                unique_views.add(post_view.ip)
        else:
            post_view = PostView.objects.create(
                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', '')
            )

        context.update({
            'count_visits': count_visits,
            'unique_views': unique_views,
        })

        return context
...