本文参考: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>