【问题标题】:Dynamically filter ListView CBV in Django 1.7在 Django 1.7 中动态过滤 ListView CBV
【发布时间】:2024-01-22 17:15:01
【问题描述】:

我已经阅读了official documentation on dynamically filtering ListView,但仍然对如何实际使用它感到困惑。

我目前有一个简单的模型,我们称之为Scholarship

class Scholarship(models.Model):
    title = models.CharField(max_length=255)
    submitted_date = models.DateField(auto_now=True, verbose_name='Date Submitted')
    EXPERIENCE_LEVEL_CHOICES = (
        ('A', 'Any'),
        ('S', 'Student'),
        ('G', 'Graduate')
    )
    experience_level = models.CharField(max_length=1, choices=EXPERIENCE_LEVEL_CHOICES, default='A')

我有一个使用 ListView 显示所有这些奖学金的页面:

views.py

from django.views.generic import ListView
from .models import Scholarship


class ScholarshipDirectoryView(ListView):
    model = Scholarship
    template_name = 'scholarship-directory.html'

urls.py

from django.conf.urls import patterns, url

from .views import ScholarshipDirectoryView

urlpatterns = patterns('',
    url(r'^$', ScholarshipDirectoryView.as_view(), name='scholarship_directory'),
)

我正在尝试在网站的主页上生成链接,这些链接将返回此 ListView 的过滤版本。例如,如果有人点击“显示研究生奖学金”链接,则只会显示带有experience_level='G' 的奖学金。

我通过 shell 返回这个查询集没有问题 -> Scholarship.objects.filter(experience_level__exact='G')

我只是不确定如何通过下拉列表或 URL 动态过滤 ListView。不打算使用插件,而是要了解 Django 中动态查询/过滤的工作原理。

【问题讨论】:

    标签: python django listview get django-views


    【解决方案1】:

    首先,您需要更改 urls.py 以便它将体验作为参数传递。像这样的:

    urlpatterns = 模式('', url(r'^(?P[ASG])$', ScholarshipDirectoryView.as_view(), name='scholarship_directory'), )

    (如果/A或/S或/G未通过,上述将返回404)

    现在,在 CBV 的 kwargs 属性中,我们将有一个名为 exp 的 kwarg,get_queryset 方法可以使用它来按经验级别进行过滤。

    类奖学金目录视图(列表视图): 模型=奖学金 template_name = 'scholarship-directory.html' def get_queryset(self): qs = super(ScholarshipDirectoryView, self).get_queryset() return qs.filter(experience_level__exact=self.kwargs['exp'])

    【讨论】:

    • 您还可以通过self.kwargs 访问get_queryset 中的kwargs。
    • 哎呀,你是对的,我忘了 self.kwargs !我改变了我的答案以反映这一点(并且更加干燥)。谢谢!
    • @Serafeim 知道如果 kwarg 不在 url 中,如何默认为 queryset 吗?我想对过滤和未过滤使用相同的 url conf
    • 不幸的是,我认为在 url 中不可能有一个可选参数 - 必须提供使用该 url conf 行的经验。因此,您需要添加另一个不带参数的 url 行(因此您将有两行用于同一视图)或回调以使用良好的旧 GET 参数来传递经验 (?exp=A)。
    • 好的。我明白。那么如果我不想在过滤列表为空时返回原始 QS 怎么办? @Serafeim