本文参考:https://www.cnblogs.com/lzc69/p/11964220.html
目的:实现如图的组合搜索
1.表结构的设计
不难看出需要三张表:分类表、地区表和电影表,其中分类和地区没有关联,分类和电影应该是多对多的关系,地区和电影应该是一对多的关系,所以model如下:
from django.db import models from django.shortcuts import redirect, render, HttpResponse # Create your models here. class Classification(models.Model): name = models.CharField(verbose_name='名称', max_length=32) class Meta: db_table = 'Classification' verbose_name_plural = '分类(视频分类)' def __str__(self): return self.name class Area(models.Model): name = models.CharField(verbose_name='地区', max_length=32) def __str__(self): return self.name classification = models.ManyToManyField(Classification) class Movie(models.Model): name = models.CharField(verbose_name='电影名', max_length=32) area = models.ForeignKey(Area,on_delete=models.DO_NOTHING) classification = models.ManyToManyField(Classification)
2.数据的处理
<1>首先需要知道前端选择了什么才能过滤数据出来,所以这里前端需要传递两个值:分类的值和地区的值(更多列则更多值)
这里采用了:url-分类id-地区id 的形式,当然也可以用?k=v的形式,但是用url-分类id-地区id 的形式爬虫会这是静态文件,权重更高,更有利于收录,所以推荐使用这种方法
用这种形式,需要url做对应配置:
urlpatterns = [ path('admin/', admin.site.urls), re_path(r"^test-(?P<Classification_id>(\d+))-(?P<Area_id>(\d+))$", views.test,name="test"), ]
这里url会以字典形式传递分类id和地区id给view函数
<2>view 函数处理
拿到分类id和地区id就能过滤出电影了,前端还需要当前选择的值进行渲染,此值又通过url传递给view的kwargs参数,所以后端处理并不复杂,如下:
from django.shortcuts import render from django.shortcuts import HttpResponse from app01.models import Classification,Area,Movie # Create your views here. def test(request,*arg,**kwargs): for k,v in kwargs.items(): kwargs[k]=int(v) # kwargs 的值是 {'Classification_id': '2', 'Area_id': '4'} # 要进行转化为数字 Classification_id=kwargs["Classification_id"] Area_id=kwargs["Area_id"] if Classification_id==0: Classification_obj=Classification.objects.all() # 若等于0则取出全部 else: # 否则过滤对应值 Classification_obj=Classification.objects.filter(id=Classification_id) if Area_id == 0: Area_obj=Area.objects.all() else: Area_obj=Area.objects.filter(id=Area_id) Class_list=Classification.objects.all() Area_list=Area.objects.all() Movie_list=Movie.objects.filter(classification__in=Classification_obj,area__in=Area_obj) print(Movie_list) return render(request, "test.html",{ "Class_list":Class_list, "Area_list":Area_list, "Movie_list":Movie_list, "url":"test", "kwargs":kwargs, })
3.前端的渲染
前端的渲染要点在于判断当前值,当前值等于item的id的时候,赋值class="active" 进行渲染,其他的值不变,只要从kwargs中取得即可,代码如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <style> .active{ color: white; background-color:crimson; } a{ display: inline-block; padding: 5px 8px; border: 1px solid #dddddd; } </style> <body> <div> {% if kwargs.Classification_id == 0 %} <a href="{{ url }}-0-{{ kwargs.Area_id }}" class="active">全部</a> {% else %} <a href="{{ url }}-0-{{ kwargs.Area_id }}" >全部</a> {% endif %} {% for item in Class_list %} {% if item.id == kwargs.Classification_id %} <a href="{{ url }}-{{ item.id }}-{{ kwargs.Area_id }}" class="active" >{{ item }}</a> {% else %} <a href="{{ url }}-{{ item.id }}-{{ kwargs.Area_id }}" >{{ item }}</a> {% endif %} {% endfor %} </div> <div> {% if kwargs.Area_id == 0 %} <a href="{{ url }}-{{ kwargs.Classification_id }}-0" class="active">全部</a> {% else %} <a href="{{ url }}-{{ kwargs.Classification_id }}-0" >全部</a> {% endif %} {% for item in Area_list %} {% if item.id == kwargs.Area_id %} <a href="{{ url }}-{{ kwargs.Classification_id }}-{{ item.id }}" class="active">{{ item }}</a> {% else %} <a href="{{ url }}-{{ kwargs.Classification_id }}-{{ item.id }}">{{ item }}</a> {% endif %} {% endfor %} </div> <div> 搜索结果: {% for item in Movie_list %} <p>{{ item.name }}</p> {% endfor %} </div> </body> </html>
声明:本文来自网络,不代表【好得很程序员自学网】立场,转载请注明出处:http://www.haodehen.cn/did125850