【问题标题】:Django filtering child objects in class-based generic list viewDjango 在基于类的通用列表视图中过滤子对象
【发布时间】:2014-01-08 09:04:16
【问题描述】:

祝大家有美好的一天!

我的应用使用了基于 django 类的通用列表视图。我有两个模型对象:通过外键链接的书籍和出版商(下面的代码)。我想使用 ListView 向出版商展示他们的书籍,但过滤书籍(只获取当前用户拥有的活动书籍)

附加信息:如果可能的话,我不想在模板中使用过滤器。 附加信息 2:我无法通过模型类中的定义使用过滤器,因为我需要访问请求对象

代码

models.py

class Publisher(models.Model):
    name = models.CharField(max_length=255)

class Book(models.Model):
    name = models.CharField(max_length=255)
    active = models.BooleanField(default=True)
    publisher = models.ForeignKey(Publisher, related_name='books')
    owner = models.ForeignKey(User)

views.py

class ListBooksByPublisher(ListView):
    model = Publisher
    template_name = 'list.html'
    context_object_name = 'books'

list.html

{% for publisher in publishers %}
    {{ publisher.name }}
    {% for book in publisher.books.all %}
        {{ book.name }}
    {% endfor %}
{% endfor %}

非常感谢任何帮助!

【问题讨论】:

    标签: django foreign-key-relationship django-class-based-views


    【解决方案1】:

    您需要覆盖视图上的 get_queryset 方法以返回您的自定义查询集

    例如:

    class ListBooksByPublisher(ListView):
        ....
        def get_queryset(self):
            return self.model.objects.filter(blablabla))
    

    希望对你有帮助

    【讨论】:

    • 我使用 get_queryset 来过滤 Publisher(父对象)。但我不明白如何使用它来过滤子对象。
    • 这是一个不同的问题 :) 在 SO 上创建另一个关于如何过滤子子对象的问题
    • 这正是我问的问题。 Django 过滤 child 对象
    • 你可能想检查这个code.djangoproject.com/ticket/17001。您正在寻找向相关对象添加过滤器
    【解决方案2】:
    #views
    class ListBooksByPublisher(ListView):
        model = Publisher
        template_name = 'list.html'
        context_object_name = 'publishers'
    #tmp
    {% for publisher in publishers %}
        {{ publisher.name }}
        {% for book in publisher.book_set.all %}
            {{ book.name }}
        {% endfor %}
    {% endfor %}
    

    【讨论】:

    • 我在这里找不到过滤器,抱歉。
    【解决方案3】:

    您可以编写自定义过滤器,返回出版商的图书列表。

    yourapp/templatetags/my_filters.py:

    from django import template
    register = template.Library()
    
    @register.filter
    def get_books(publisher):
        return publisher.book_set.filter(YOUR_CUSTOM_FILTER)
    

    您的模板:

    {% load get_books from my_filters %}
    ...
    {% for publisher in publishers %}
        {{ publisher.name }}
        {% for book in publisher|get_books %}
            {{ book.name }}
        {% endfor %}
    {% endfor %}
    

    另一种方法是将额外的数据传递给您的视图:

    class ListBooksByPublisher(ListView):
        ...
        def get_context_data(self, **kwargs):
            context = super(ListBooksByPublisher, self).get_context_data(**kwargs)
            context['publishers_with_books'] = your_custom_data_structure
            return context
    

    【讨论】:

    • 请记住一件事:如果您的要求对于 CBV 来说过于复杂,那么使用基于函数的视图并没有错。
    猜你喜欢
    • 1970-01-01
    • 2015-11-04
    • 2011-10-24
    • 1970-01-01
    • 1970-01-01
    • 2011-09-03
    • 2018-11-19
    • 1970-01-01
    • 2011-08-14
    相关资源
    最近更新 更多