Django面试问题整理:基于类的视图三个常用方法的作用

get_queryset()方法

正如其名,该方法可以返回一个量身定制的对象列表。当我们使用Django自带的ListView展示所有对象列表时,ListView默认会返回Model.objects.all()。

<code>from django.views.generic import ListView
from .models import Article

class IndexView(ListView):

model = Article/<code>

然而这可能不是我们所需要的。当我们希望只展示作者自己发表的文章列表且按文章发布时间逆序排列时,我们就可以通过更具体的get_queryset()方法来返回一个我们想要显示的对象列表。

<code>from django.views.generic import ListView
from .models import Article
from django.utils import timezone

class IndexView(ListView):

   template_name = 'blog/article_list.html'
   context_object_name = 'latest_articles'

   def get_queryset(self):
       return Article.objects.filter(author = self.request.user).order_by('-pub_date')/<code>

get_context_data()方法

get_context_data()可以用于给模板传递模型以外的内容或参数,非常有用。例如现在的时间并不属于Article模型。如果你想把现在的时间传递给模板,你还可以通过重写get_context_data方法(如下图所示)。因为调用了父类的方法:

<code>from django.views.generic import ListView
from .models import Article
from django.utils import timezone

class IndexView(ListView):

   queryset = Article.objects.all().order_by("-pub_date")
   template_name = 'blog/article_list.html'
   context_object_name = 'latest_articles'

   def get_context_data(self, **kwargs):
       context = super().get_context_data(**kwargs)
       context['now'] = timezone.now() #只有这行代码有用
       return context/<code>

get_object()方法

DetailView和EditView都是从URL根据pk或其它参数调取一个对象来进行后续操作。下面代码通过DetailView展示一篇文章的详细信息。

<code>from django.views.generic import DetailView
from django.http import Http404
from .models import Article
from django.utils import timezone

class ArticleDetailView(DetailView):

   queryset = Article.objects.all().order_by("-pub_date") #等同于model = Article
   template_name = 'blog/article_detail.html'
   context_object_name = 'article'/<code>

然而上述代码可能满足不了你的需求。比如你希望一个用户只能查看或编辑自己发表的文章对象。当用户查看别人的对象时,返回http 404错误。这时候你可以通过更具体的get_object()方法来返回一个更具体的对象。代码如下:

<code>from django.views.generic import DetailView
from django.http import Http404

from .models import Article
from django.utils import timezone

class ArticleDetailView(DetailView):

   queryset = Article.objects.all().order_by("-pub_date")
   template_name = 'blog/article_detail.html'
   context_object_name = 'article'

   def get_object(self, queryset=None):
       obj = super().get_object(queryset=queryset)
       if obj.author != self.request.user:
           raise Http404()
       return obj/<code>


分享到:


相關文章: