如何在Django视图中定义get_queryset和get_context_data?

3 投票
1 回答
8459 浏览
提问于 2025-04-18 17:05

我想展示一个树形结构,里面有作者和每个作者写的书籍作为子项,就像图片中展示的那样。我有两个模型,作者书籍,它们之间是一对多的关系。

#models.py
from django.db import models

class Author(models.Model):
    Name = models.CharField(max_length = 250)

    def __unicode__(self):
        return self.Name

class Book(models.Model):
    Title = models.CharField(max_length = 250)

    def __unicode__(self):
        return self.Title


#views.py
from django.shortcuts import render, get_object_or_404
from django.views.generic import TemplateView, ListView

from .models import InstanciaJudicial, SedeJudicial

class Prueba(ListView):
    model = SedeJudicial
    template_name = 'instancias/pruebas.html'

我知道我定义了get_querysetget_context_data,但是我不太清楚我是怎么做到的。

1 个回答

12

首先,你需要在你的模型之间建立一个ForeignKey关系。

#models.py
from django.db import models

class Book(models.Model):
    title = models.CharField(max_length = 250)
    author = models.ForeignKey(Author, related_name="books")

    def __unicode__(self):
        return self.Title

现在,在你的视图中,你可以通过重写get_queryset方法来获取作者列表,像这样:

#views.py
from django.shortcuts import render, get_object_or_404
from django.views.generic import TemplateView, ListView

from .models import Author

class BooksByAuthorList(ListView):
    model = Book
    template_name = 'instancias/pruebas.html'

    def get_queryset(self):
        return Author.objects.prefetch_related("books").all()

只用上面的视图,你就可以在模板中使用:

<ul>
{% for author in object_list %}
  <li>{{author.name}}</li><ul>
  {% for book in author.books.all %}
    <li>book.title</li>
  {% endfor %}
  </ul>
{% endfor %}
</ul>

假设你想自定义一下,让上下文变量不再是通用的object_list,而是更符合主题的authors

只需这样修改你的视图:

class BooksByAuthorList(ListView):
    model = Author
    template_name = 'instancias/pruebas.html'
    context_object_name = 'authors'        

    def get_queryset(self):
        return Author.objects.prefetch_related("books").all()

注意,你现在还不需要get_context_data

假设你想加入一些额外的数据,你只需重写get_context_data,在这种情况下,你需要先调用父类的get_context_data方法,以保留已经在上下文中的对象列表。

只需这样做:

    def get_context_data(self, *args, **kwargs):
        # Call the base implementation first to get a context
        context = super(BooksByAuthorList, self).get_context_data(*args, **kwargs)
        # add whatever to your context:
        context['whatever'] = "MORE STUFF"
        return context

get_context_data的参数由你的路由决定。*args**kwargs应该用与你的视图和路由相关的具体内容替换。

撰写回答