我如何在基于类的视图Django中限制未经身份验证的用户的帖子视图

时间:2019-03-02 14:05:08

标签: python django

我是django的新手。在我的项目中,我想创建一个可以查看某些帖子的主页,但是如果用户注册或通过身份验证,则可以查看网站上所有可用的帖子。到目前为止,我已经创建了一个视图,该视图可以呈现主页上的所有帖子,但是我想限制它们。

我正在使用基于类的视图。

  

posts / views.py

from django.views.generic import ListView, DetailView
from .models import Post

class PostListView(ListView):
    model = Post
    template_name = 'posts/home.html'
    context_object_name = 'posts'
    ordering = ['-date_posted']


class PostDetailView(DetailView):
    model = Post
    template_name = 'posts/post_detail.html'
  

posts / models.py

from django.db import models
from django.utils import timezone
from slugger import AutoSlugField
from django.contrib.auth.models import User
from django.urls import reverse
# Create your models here.

def upload_location(instance, filename):
    return "%s/%s" %(instance.slug, filename)

class Category(models.Model):
    title = models.CharField(max_length= 60)
    slug = AutoSlugField(populate_from='title')
    parent = models.ForeignKey('self',blank=True, null=True ,related_name='children',on_delete=models.CASCADE)
    updated = models.DateTimeField(auto_now=True, auto_now_add=False)
    timestamp = models.DateTimeField(auto_now=False, auto_now_add=True)

    def __unicode__(self):
        return self.title

    def __str__(self):
        return self.title



class Post(models.Model):
    title = models.CharField(max_length=120)
    slug = AutoSlugField(populate_from='title')
    image = models.ImageField(
        upload_to=upload_location,
        null=True, 
        blank=True,
    )
    category = models.ForeignKey(Category, on_delete=models.CASCADE)
    content = models.TextField()
    date_posted = models.DateTimeField(default=timezone.now)
    author = models.ForeignKey(User, on_delete=models.CASCADE)


    def __str__(self):
        return self.title


    def get_absolute_url(self):
        return reverse("posts-detail", kwargs={"pk": self.pk})

2 个答案:

答案 0 :(得分:1)

ListView中,默认的QuerySet是所有对象。在您的情况下,将model设置为Post,则默认查询集为Post.objects.all()

您可以覆盖get_queryset()的{​​{1}}方法。查看this website,以充分了解Django CBV。

ListView

答案 1 :(得分:1)

重定向用户

如果用户未登录,则可以使用LoginRequiredMixin [Django-doc]阻止用户查看视图。在这种情况下,默认行为是重定向到登录页面。

您可以将混合添加到视图中,例如:

# posts/views.py

from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic import ListView, DetailView
from .models import Post

class PostListView(LoginRequiredMixin, ListView):
    model = Post
    template_name = 'posts/home.html'
    context_object_name = 'posts'
    ordering = ['-date_posted']


class PostDetailView(LoginRequiredMixin, DetailView):
    model = Post
    template_name = 'posts/post_detail.html'

文档描述了如果要将用户重定向到另一个页面,可以将redirect_to类属性设置为其他内容。

显示没有Post个页面(或对其进行过滤)

您还可以决定呈现页面,但不包含任何Post对象。我们可以通过修补get_queryset方法来解决这个问题:

# posts/views.py

from django.views.generic import ListView, DetailView
from .models import Post

class PostListView(ListView):
    model = Post
    template_name = 'posts/home.html'
    context_object_name = 'posts'
    ordering = ['-date_posted']

    def get_queryset(self):
        if not self.request.user.is_authenticated:
            return Post.objects.none()
        else:
            return super().get_queryset()


class PostDetailView(DetailView):
    model = Post
    template_name = 'posts/post_detail.html'

    def get_queryset(self):
        if not self.request.user.is_authenticated:
            return Post.objects.none()
        else:
            return super().get_queryset()