Django 实现组合搜索

本文参考:https://www.cnblogs.com/lzc69/p/11964220.html

目的:实现如图的组合搜索
Django 实现组合搜索

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>
上一篇:django中的*args 与 **kwargs使用介绍


下一篇:python 面向对象专题(十四):MetaClass使用