西游之路——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
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 ]
注意:
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())
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>
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())
注意:条件之间是有关联,先理清条件之间的关系,然后是条件跟结果的关系
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>
                    
                

                
            
        
浙公网安备 33010602011771号