博客五部曲之一 - 简单博客
1473 浏览 5 years, 11 months
36 模型管理器和草稿处理
版权声明: 转载请注明出处 http://www.codingsoho.com/用户不应该在帖子列表里看到草稿和日期在将来的帖子,我们应该把它过滤掉。 一种比较简单的方法是直接在QuerySet里添加filter,例如Post.objects.filter(publish__lte=timezone.now()).filter(draft=False) 但是在每个地方都用这个方法过滤效率并不高,Django提供的Model Manager能更好的处理这种情况。
class PostManager(models.Manager):
def active(self, *args, **kwargs):
return super(PostManager, self).filter(draft=False).filter(publish__lte=timezone.now())
class Post(models.Model):
objects = PostManager()
取名objects是一个惯例,当然你也可以取其他名字,但不建议,因为可能会给其他开发者带来混乱。
定义active方法,过滤出需要呈现给普通用户的帖子列表。也可以定义all方法覆盖默认的方法,但是这样会导致其他的一些默认行为受影响,需谨慎。
在post_list视图里,默认用户只能查看过滤的帖子,如果是超级用户或者员工,可以查看所有的。
def post_list(request):
queryset_list = Post.objects.active()
if request.user.is_staff or request.user.is_superuser:
queryset_list = Post.objects.all()
对于草稿和将来的帖子,对于非员工和超级用户,除了不能在列表视图显示,也不能在详情视图显示。
def post_detail(request, slug=None):
instance = get_object_or_404(Post, slug=slug)
if instance.draft or instance.publish > timezone.now().date():
if not request.user.is_staff or not request.user.is_superuser:
raise Http404
对于编辑类视图(创建,更新和删除),本来之前就有判断了,所以不需要特别修改。
修改帖子列表显示,针对草稿和发布时间在将来的帖子做一些特别的处理
{% if object.draft %} <h3>Draft {% if object.publish > today %}Staff Only : Future Post{% endif %}</h3>{% endif %}
<h3><a href="{{ object.get_absolute_url }}">{{object.title}}</a> <small>{{object.timestamp|timesince}}</small></h3>