西游之路——python全栈——组合搜索

一、一对多关系

 1 from django.db import models
 2 
 3 class Direction(models.Model):
 4     '''
 5     方向:自动化  测试  运维  前端
 6     '''
 7     weight = models.IntegerField(verbose_name='权重', default=0)
 8     name = models.CharField(verbose_name='名称', max_length=32, unique=True)
 9     classification = models.ManyToManyField('Classification')
10     class Meta:
11         db_table = 'Direction'
12         verbose_name_plural = '方向(视频方向)'
13     def __str__(self):
14         return self.name
15 
16 class Classification(models.Model):
17     '''
18     分类:python Linux JavaScript OpenStack node.js
19     '''
20     weight = models.IntegerField(verbose_name='权重', default=0)
21     name = models.CharField(verbose_name='名称', max_length=32, unique=True)
22     class Meta:
23         db_table = 'Classification'
24         verbose_name_plural = '分类(视频分类)'
25     def __str__(self):
26         return self.name
27 
28 class Level(models.Model):
29     title = models.CharField(max_length=32)
30     class Meta:
31         verbose_name_plural = '难度级别'
32     def __str__(self):
33         return self.title
34 
35 class Video(models.Model):
36     status_choice = (
37         (2, '上线'),
38         (1, '下线'),
39     )
40     # level_choice = (
41     #     (1, '初级'),
42     #     (2, '中级'),
43     #     (3, '高级'),
44     # )
45     status = models.IntegerField(verbose_name='状态', choices=status_choice, default=1)
46     # level = models.IntegerField(verbose_name='级别', choices=level_choice, default=1)
47     level = models.ForeignKey('Level', null=True, blank=True,on_delete=models.CASCADE)
48 
49     classification = models.ForeignKey('Classification', null=True, blank=True,on_delete=models.CASCADE)
50 
51     weight = models.IntegerField(verbose_name='权重', default=0)
52 
53     title = models.CharField(verbose_name='标题', max_length=32)
54     summary = models.CharField(verbose_name='简介', max_length=32)
55     img = models.ImageField(verbose_name='图片', upload_to='./static/images/Video/')
56     href = models.CharField(verbose_name='视频地址',max_length=256)
57 
58     create_date = models.DateTimeField(auto_now_add=True)
59 
60     class Meta:
61         db_table = 'Video'
62         verbose_name_plural = '视频'
63 
64     def __str__(self):
65         return self.title
models.py数据库表设计
1 urlpatterns = [
2     re_path('admin/', admin.site.urls),
3     re_path('video-(?P<classification_id>(d+))-(?P<level_id>(d+))-(?P<status>(d+)).html/$', views.video),
4     re_path('video2-(?P<direction_id>(d+))-(?P<classification_id>(d+))-(?P<level_id>(d+)).html/$', views.video2),
5 ]
URL操作

注意

  1、大写的P

  2、伪造静态页面

 1 from django.shortcuts import render
 2 from app01 import models
 3 
 4 def video(request,*args,**kwargs):
 5     condition = {
 6         # 'level_id':1,
 7         # 'classification_id':1
 8     }
 9     # 构造查询字典
10     for k,v in kwargs.items():
11         tem = int(v)
12         kwargs[k] = tem
13         # 排除0
14         if tem:
15             condition[k] = tem
16     # 循环复制,构造列表字典,以便HTML中调用方式看起来合乎常理
17     status_list = list(map(lambda x:{'id':x[0],'name':x[1]},models.Video.status_choice))  # 普通字段提取 
18 
19     direction_list = models.Direction.objects.all()
20     class_list = models.Classification.objects.all()
21     level_list = models.Level.objects.all()
22     # 字典和列表加**
23     video_list = models.Video.objects.filter(**condition)
24 
25     return render(request, 'video.html',locals())
Views.py操作
 1 <head>
 2     <meta charset="UTF-8">
 3     <title>Title</title>
 4     <style>
 5         .condition a{
 6             display: inline-block;
 7             padding: 5px 8px;
 8             border: 1px solid #dddddd;
 9         }
10         .condition a.active{
11             background-color: coral;
12             color: white;
13         }
14     </style>
15 </head>
16 <body>
17 <div class="condition">
18     <h1>筛选</h1>
19     <div>
20         {# 高亮显示选中 #}
21         {% if kwargs.classification_id == 0 %}
22             <a class="active" href="/video-0-{{kwargs.level_id}}-{{kwargs.status}}.html">全部</a>
23         {% else %}
24             <a href="/video-0-{{kwargs.level_id}}-{{kwargs.status}}.html">全部</a>
25         {% endif %}
26         {% for item in class_list %}
27             {% if item.id == kwargs.classification_id %}
28                 <a class="active" href="/video-{{item.id}}-{{kwargs.level_id}}-{{kwargs.status}}.html">{{item.name}}</a>
29             {% else %}
30                 <a href="/video-{{item.id}}-{{kwargs.level_id}}-{{kwargs.status}}.html">{{item.name}}</a>
31             {% endif %}
32         {% endfor %}
33     </div>
34     <div>
35         {% if kwargs.level_id == 0 %}
36             <a class="active" href="/video-{{kwargs.classification_id}}-0-{{kwargs.status}}.html">全部</a>
37         {% else %}
38             <a href="/video-{{kwargs.classification_id}}-0-{{kwargs.status}}.html">全部</a>
39         {% endif %}
40         {% for item in level_list %}
41             {% if item.id == kwargs.level_id %}
42                 <a class="active" href="/video-{{kwargs.classification_id}}-{{item.id}}-{{kwargs.status}}.html">{{item.title}}</a>
43             {% else %}
44                 <a href="/video-{{kwargs.classification_id}}-{{item.id}}-{{kwargs.status}}.html">{{item.title}}</a>
45             {% endif %}
46         {% endfor %}
47     </div>
48     <div>
49         {% if kwargs.status == 0 %}
50             <a class="active" href="/video-{{kwargs.classification_id}}-{{kwargs.level_id}}-0.html">全部</a>
51         {% else %}
52             <a href="/video-{{kwargs.classification_id}}-{{kwargs.level_id}}-0.html">全部</a>
53         {% endif %}
54         {% for item in status_list %}
55             {% if item.id == kwargs.status %}
56                 <a class="active" href="/video-{{kwargs.classification_id}}-{{kwargs.level_id}}-{{item.id}}.html">{{item.name}}</a>
57             {% else %}
58                 <a href="/video-{{kwargs.classification_id}}-{{kwargs.level_id}}-{{item.id}}.html">{{item.name}}</a>
59             {% endif %}
60         {% endfor %}
61     </div>
62 </div>
63 <h1>结果</h1>
64     <div>
65         {% for row in video_list %}
66             <div>{{row.title}}</div>
67             <div>{{row.summary}}</div>
68             <div>{{row.img}}</div>
69         {% endfor %}
70     </div>
71 </body>
HTML操作

  1、筛选条件间互不影响

  2、发送URL请求时,只是选中ID变化,其他保持不变

二、多对多

1、数据库表设计和URL见上

2、

 1 def video2(request, *args, **kwargs):
 2     # 构造查询字典
 3     for k,v in kwargs.items():
 4         kwargs[k] = int(v)
 5     # 提取出各自ID
 6     direction_id = kwargs.get('direction_id')
 7     classification_id = kwargs.get('classification_id')
 8     level_id = kwargs.get('level_id')
 9 
10     # 把对Video的筛选条件存入condition字典中
11     condition = {}
12     if direction_id == 0:
13         class_list = models.Classification.objects.all()
14         if classification_id == 0:
15             pass
16         else:
17             condition['classification_id'] = classification_id
18     else:
19         direction_obj = models.Direction.objects.filter(id=direction_id).first()
20         class_list = direction_obj.classification.all()
21 
22         vlist = direction_obj.classification.all().values_list('id')
23         # 判断方向无分类情况
24         if not vlist:
25             classification_id_list = []
26         else:
27             # v=[(1,2.3),(4,5.6)]   =>  list(zip(*v))   =>   [(1, 4), (2, 5), (3, 6)]
28             #                           list(zip(*v))[0]  =>  (1,4)
29             classification_id_list = list(zip(*vlist))[0]   ######
30         if classification_id == 0:
31             condition['classification_id__in'] = classification_id_list
32         else:
33             if classification_id in classification_id_list:
34                 condition['classification_id'] = classification_id
35             else:
36                 # 切换方向时,选中的分类不在此方向中则清零(跳转到全部)
37                 kwargs['classification_id'] = 0    ######
38                 condition['classification_id__in'] = classification_id_list
39 
40     # 加入level对video的筛选条件
41     if level_id == 0:
42         pass
43     else:
44         condition['level_id'] = level_id
45 
46     direction_list = models.Direction.objects.all()
47     level_list = models.Level.objects.all()
48     video_list = models.Video.objects.filter(**condition).all()
49 
50     return render(request,'video2.html',locals())
Views.py操作

注意:条件之间是有关联,先理清条件之间的关系,然后是条件跟结果的关系

3、

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6     <style>
 7         .condition a{
 8             display: inline-block;
 9             padding: 5px 8px;
10             border: 1px solid #dddddd;
11         }
12         .condition a.active{
13             background-color: coral;
14             color: white;
15         }
16     </style>
17 </head>
18 <body>
19 <div class="condition">
20     <h1>筛选</h1>
21     <div>
22         {% if kwargs.direction_id == 0 %}
23             <a class="active" href="/video2-0-{{kwargs.classification_id}}-{{kwargs.level_id}}.html">全部</a>
24         {% else %}
25              <a href="/video2-0-{{kwargs.classification_id}}-{{kwargs.level_id}}.html">全部</a>
26         {% endif %}
27         {% for item in direction_list %}
28             {% if item.id == kwargs.direction_id %}
29                 <a class="active" href="/video2-{{item.id}}-{{kwargs.classification_id}}-{{kwargs.level_id}}.html">{{item.name}}</a>
30             {% else %}
31                 <a href="/video2-{{item.id}}-{{kwargs.classification_id}}-{{kwargs.level_id}}.html">{{item.name}}</a>
32             {% endif %}
33         {% endfor %}
34     </div>
35     <div>
36         {% if kwargs.classification_id == 0 %}
37             <a class="active" href="/video2-{{kwargs.direction_id}}-0-{{kwargs.level_id}}.html">全部</a>
38         {% else %}
39              <a href="/video2-{{kwargs.direction_id}}-0-{{kwargs.level_id}}.html">全部</a>
40         {% endif %}
41         {% for item in class_list %}
42             {% if item.id == kwargs.classification_id %}
43                 <a class="active" href="/video2-{{kwargs.direction_id}}-{{item.id}}-{{kwargs.level_id}}.html">{{item.name}}</a>
44             {% else %}
45                 <a href="/video2-{{kwargs.direction_id}}-{{item.id}}-{{kwargs.level_id}}.html">{{item.name}}</a>
46             {% endif %}
47         {% endfor %}
48     </div>
49     <div>
50         {% if kwargs.level_id == 0 %}
51             <a class="active" href="/video2-{{kwargs.direction_id}}-{{kwargs.classification_id}}-0.html">全部</a>
52         {% else %}
53              <a href="/video2-{{kwargs.direction_id}}-{{kwargs.classification_id}}-0.html">全部</a>
54         {% endif %}
55         {% for item in level_list %}
56             {% if item.id == kwargs.level_id %}
57                 <a class="active" href="/video2-{{kwargs.direction_id}}-{{kwargs.classification_id}}-{{item.id}}.html">{{item.title}}</a>
58             {% else %}
59                 <a href="/video2-{{kwargs.direction_id}}-{{kwargs.classification_id}}-{{item.id}}.html">{{item.title}}</a>
60             {% endif %}
61         {% endfor %}
62     </div>
63 </div>
64 <h1>结果</h1>
65     <div>
66         {% for item in video_list %}
67             <a href="">{{item.title}}</a>
68         {% endfor %}
69     </div>
70 
71 </body>
72 </html>
HTML操作
原文地址:https://www.cnblogs.com/Lujun1028/p/9639135.html