博客五部曲之一 - 简单博客


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>