我是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})
答案 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()