在Django 1.7中动态过滤ListView CBV

12 投票
1 回答
9099 浏览
提问于 2025-04-19 18:55

我看过关于动态过滤 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' 的奖学金。

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

我只是对如何通过下拉菜单或 URL 动态过滤 ListView 感到不确定。我不想使用插件,而是想理解在 Django 中动态查询/过滤是怎么回事。

1 个回答

15

首先,你需要修改你的urls.py文件,让它能够把经验值作为一个参数传递。可以像这样做:

urlpatterns = patterns('',
    url(r'^(?P<exp>[ASG])$', ScholarshipDirectoryView.as_view(), name='scholarship_directory'),
)

(如果没有传递/A、/S或/G,以上代码会返回404错误)

现在,在CBV的kwargs属性中,我们会有一个名为exp的参数,这个参数可以被get_queryset方法用来根据经验水平进行筛选。

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

    def get_queryset(self):
        qs = super(ScholarshipDirectoryView, self).get_queryset()
        return qs.filter(experience_level__exact=self.kwargs['exp'])

撰写回答