职位搜索
本课属于 Coddy Django 学习旅程的“基于类的视图”单元。第 18 课,共 18 课。
最后一个功能是在职位页面上添加搜索框。访客输入 developer,点击“搜索”,就只会看到标题中包含这个词的职位。
搜索表单使用 GET,因此这个词会出现在 URL 中,形式为 ?q=developer,链接或书签会保留它。视图在 get_queryset() 中读取它,就像读取 ?city= 一样。人们输入时大小写可能不同,因此要使用忽略大小写的查询方式进行匹配。
在模板中,当前请求是 request,所以 {{ request.GET.q }} 就是搜索的词:把它放进搜索框的值中。
筛选条件可以串联:如果有城市,就先按城市缩小范围;如果有搜索词,再按搜索词筛选。分页链接已经使用 {% querystring %},所以翻页时搜索条件会保留下来。
挑战
中等添加职位搜索框。
- 在
jobs/views.py中的JobListView.get_queryset()里,像读取city一样,从request.GET读取q。如果设置了q,就只保留标题中包含它的职位,不区分大小写。 - 在
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")
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
基于类的视图中的所有课
自己练习: Django 在线编辑器