Menu
CoddyTech

职位搜索

本课属于 Coddy Django 学习旅程的“基于类的视图”单元。第 18 课,共 18 课。

最后一个功能是在职位页面上添加搜索框。访客输入 developer,点击“搜索”,就只会看到标题中包含这个词的职位。

搜索表单使用 GET,因此这个词会出现在 URL 中,形式为 ?q=developer,链接或书签会保留它。视图在 get_queryset() 中读取它,就像读取 ?city= 一样。人们输入时大小写可能不同,因此要使用忽略大小写的查询方式进行匹配。

在模板中,当前请求是 request,所以 {{ request.GET.q }} 就是搜索的词:把它放进搜索框的值中。

筛选条件可以串联:如果有城市,就先按城市缩小范围;如果有搜索词,再按搜索词筛选。分页链接已经使用 {% querystring %},所以翻页时搜索条件会保留下来。

challenge icon

挑战

中等

添加职位搜索框。

  1. 在 jobs/views.py 中的 JobListView.get_queryset() 里,像读取 city 一样,从 request.GET 读取 q。如果设置了 q,就只保留标题中包含它的职位,不区分大小写。
  2. 在 job_list.html 中的 <h1> 下方添加一个 GET 表单:添加一个名为 q 的输入框,其值为 request.GET.q,并添加一个 Search 按钮。

搜索 developer:你会看到 4 个职位,输入框中会保留这个词。

亲手试试

from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
from django.urls import reverse_lazy
from django.views.generic import CreateView, DeleteView, DetailView, ListView, TemplateView, UpdateView

from .models import Job


class HomeView(TemplateView):
    template_name = "jobs/home.html"

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context["count"] = Job.objects.count()
        context["latest"] = Job.objects.order_by("-posted").first()
        return context


class AboutView(TemplateView):
    template_name = "jobs/about.html"


class JobListView(ListView):
    model = Job
    context_object_name = "jobs"
    ordering = ["-posted"]
    paginate_by = 5

    def get_queryset(self):
        jobs = super().get_queryset()
        city = self.request.GET.get("city")
        if city:
            jobs = jobs.filter(city=city)
        return jobs


class JobDetailView(DetailView):
    model = Job


class JobCreateView(LoginRequiredMixin, CreateView):
    model = Job
    fields = ["title", "company", "city", "salary", "description"]

    def form_valid(self, form):
        form.instance.posted_by = self.request.user
        return super().form_valid(form)


class JobUpdateView(LoginRequiredMixin, UserPassesTestMixin, UpdateView):
    model = Job
    fields = ["title", "company", "city", "salary", "description"]

    def test_func(self):
        return self.get_object().posted_by == self.request.user


class JobDeleteView(LoginRequiredMixin, UserPassesTestMixin, DeleteView):
    model = Job
    success_url = reverse_lazy("jobs:list")

    def test_func(self):
        return self.get_object().posted_by == self.request.user


class MyJobsView(LoginRequiredMixin, ListView):
    template_name = "jobs/my_jobs.html"
    context_object_name = "jobs"

    def get_queryset(self):
        return Job.objects.filter(posted_by=self.request.user).order_by("-posted")
quiz icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

基于类的视图中的所有课

自己练习: Django 在线编辑器