day24-组合搜索组件

一、前言

  我们学习一下组合搜索组件,我们在筛选内容的时候会经常用到,这边我们就来一个初版,因为这个后面还需要进行进一步优化,下面我们就来看看,我们这搜索组件是咋写的,这个东西我们会经常用到的,所以要认真的写一下,我们来根据汽车之家的效果图:

  

  以上是汽车之家的页面,我们也是照着汽车之家的格式写一个,写成一个,以:http://127.0.0.1:8000/article-2-4.html  这样的方式访问。

二、组合搜索组件

2.1、模型(model)

说明:是数据库的设置,这个里面的数据都是自己填写的,后面我们贴出来了,创建数据库之前需要执行python manage.py makemigrations和 python manage.py migrate。

from django.db import models

class Category(models.Model):
    """
    文章分类表
    """
    caption = models.CharField(max_length=16)

class ArticleType(models.Model):
    """
    文章类型表
    """
    caption = models.CharField(max_length=16)

class Article(models.Model):
    """
    文章表
    """
    title = models.CharField(max_length=32)
    content = models.CharField(max_length=255)
    category = models.ForeignKey(Category,on_delete=models.CASCADE)
    article_type = models.ForeignKey(ArticleType,on_delete=models.CASCADE)

数据创建如下:

2.2、路由的设置(urls)

说明:我们在路由里面设置两个参数,因为我们在访问的时候,通过类似:http://127.0.0.1:8000/article-2-4.html(2:文章类型id,4:文章分类id)

from django.urls import path,re_path
from app01 import views

urlpatterns = [
    re_path(r'^article-(?P<article_type_id>\d+)-(?P<category_id>\d+).html$',views.article,name='article')
]

2.3、article函数编写

说明:编写article函数传文章对象,文章类型和文章分类对象过去,还有前端通过 传 article_type_id 和 category_id 到前端

from django.shortcuts import render
from app01 import models

def article(request,*args,**kwargs):
    # print(kwargs) #{'category_id': '0', 'article_type_id': '0'}
    # print(request.path_info)
    # from django.urls import reverse
    # url = reverse('article',kwargs=kwargs) #用name+参数 可以生成指定url
    # print(url)
    condition = {}
    #如果显示全部的话,则显示所有文章
    for k,v in kwargs.items():
        kwargs[k] = int(v)  #需要把value的值转化为整数,跟后面的id数据类型一样
        if v == '0':
            pass
        else:
            condition[k] = v  #获取传过来的article_type_id 和 category_id
    article_type_list = models.ArticleType.objects.all()
    catagory_list = models.Category.objects.all()
    result = models.Article.objects.filter(**condition)  #两个article_type_id 和 category_id组合成一个条件帮我筛选文章
    return render(request,'article.html',
                  {
                    'result':result,
                    'article_type_list':article_type_list,  #文章类型
                    'catagory_list':catagory_list,  #文章分类
                    'arg_dict':kwargs,  #传过来的 article_type_id 和 category_id
                   }
                  )
article.py

2.4、article.html模板

说明:article函数获取的数据全部映射到article.html模板上

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .condition a {
            display: inline-block;
            padding: 3px 5px;
            border: 1px solid #dddddd;
            margin: 5px;
            text-decoration: none;
        }
        .condition a.active{
            background-color: cadetblue;
        }
    </style>
</head>
<body>
    <h1>过滤条件</h1>
    <div class="condition">
        <div>
            <!--http://127.0.0.1:8000/article-article_type_id-category_id.html-->
            <!--判断当前文章类型id是否为0,为0的话,我只传文章分类id进去就行了,生成url-->
            {% if arg_dict.article_type_id == 0 %}
                <a class="active" href="/article-0-{{ arg_dict.category_id }}.html">全部</a>
            {% else %}
                <a href="/article-0-{{ arg_dict.category_id }}.html">全部</a>
            {% endif %}

            {% for row in article_type_list %}
                <!--当前的文章类型id和传进去的article_type_id是否相等-->
                {% if row.id == arg_dict.article_type_id %}
                    <!--我只拿到自己当前的article_type_id和当前传category_id生成url-->
                    <a class="active" href="/article-{{ row.id }}-{{ arg_dict.category_id }}.html">{{ row.caption }}</a>
                {% else %}
                    <a href="/article-{{ row.id }}-{{ arg_dict.category_id }}.html">{{ row.caption }}</a>
                {% endif %}
            {% endfor %}
        </div>

        <div>
            <!--http://127.0.0.1:8000/article-article_type_id-category_id.html-->
            <!--判断当前文章分类id是否为0,为0的话,我只传文章类型id进去就行了-->
            {% if arg_dict.category_id == 0 %}
                <a class="active" href="/article-{{ arg_dict.article_type_id }}-0.html">全部</a>
            {% else %}
                <a href="/article-{{ arg_dict.article_type_id }}-0.html">全部</a>
            {% endif %}

            {% for row in catagory_list %}
                <!--当前的文章分类id和传进去的category_id是否相等,生成url-->
                {% if row.id == arg_dict.category_id %}
                    <!--我只拿到当前传article_type_id和我自己当前的category_id生成url-->
                    <a class="active"  href="/article-{{ arg_dict.article_type_id }}-{{ row.id }}.html">{{ row.caption }}</a>
                {% else %}
                    <a href="/article-{{ arg_dict.article_type_id }}-{{ row.id }}.html">{{ row.caption }}</a>
                {% endif %}
            {% endfor %}
        </div>
    </div>

    <h1>查询结果</h1>
    <ul>
        {% for row in result %}
            <li>{{ row.id }}-{{ row.title }}</li>
        {% endfor %}
    </ul>
</body>
</html>
article.html

注意:中间的逻辑思想已经写入article.html模板语言中。

我们生成的效果图如下:

三、优化article.html(simple_tag方式)

  有些同学就说了,你上面article.html模板写的太啰嗦了,能不能有简单的方式呐,有的,我们今天就用我们学过的知识点 simple_tag 的方式来改一下,具体 simple_tag 如何使用,请查看:http://www.cnblogs.com/zhangqigao/articles/8658579.html,这边我专门写了一篇博客出来,好啦,下面我们就来改造吧!

3.1、创建simple_tag函数

说明:app01->创建templatetags文件夹->创建filter.py文件,三个函数:filter_all(过滤全部)、filter_article_type(过滤文章类型)、filter_category_type(过滤文章分类),三个分别对应的上面article.html中的过滤。

from django import template
from django.utils.safestring import mark_safe

register = template.Library() #这个register对象名字也不能是其他名字,只能叫register

@register.simple_tag
def filter_all(arg_dict,k):
    """
    过滤全部选项
    :param arg_dict: 
    :param k: 
    :return: 
    """
    #假设我们只有article_type_id和category_id
    if k == "article_type_id": #传入article_type_id
        n1 = arg_dict['article_type_id']
        n2 = arg_dict['category_id']
        if n1 == 0:
            ret = '<a class="active" href="/article-0-%s.html">全部</a>'%n2
        else:
            ret = '<a href="/article-0-%s.html">全部</a>'%n2
    else:
        n1 = arg_dict['category_id'] #category_id
        n2 = arg_dict['article_type_id']
        if n1 == 0:
            ret = '<a class="active" href="/article-%s-0.html">全部</a>'%n2
        else:
            ret = '<a href="/article-%s-0.html">全部</a>'%n2

    return mark_safe(ret)

@register.simple_tag
def filter_article_type(article_type_list,arg_dict):
    """
    过滤文章类型
    :param article_type_list: 
    :param arg_dict: 
    :return: 
    """
    ret = list()
    for row in article_type_list:
        if row.id == arg_dict['article_type_id']:
            temp = '<a class="active" href="/article-%s-%s.html">%s</a>'%(row.id,arg_dict['category_id'],row.caption,)
        else:
            temp = '<a href="/article-%s-%s.html">%s</a>'%(row.id,arg_dict['category_id'],row.caption,)
        ret.append(temp)

    return mark_safe(''.join(ret))

@register.simple_tag
def filter_category_type(catagory_list,arg_dict):
    """
    过滤文章目录
    :param catagory_list:
    :param arg_dict:
    :return:
    """
    ret = list()
    for row in catagory_list:
        if row.id == arg_dict['category_id']:
            temp = '<a class="active" href="/article-%s-%s.html">%s</a>'%(arg_dict['article_type_id'],row.id,row.caption,)
        else:
            temp = '<a href="/article-%s-%s.html">%s</a>'%(arg_dict['article_type_id'],row.id,row.caption,)
        ret.append(temp)

    return mark_safe(''.join(ret))
filter.py

3.2、article.html改进

说明:我们这边需要导入filter模块,然后再使用函数

{% load filter %} <!--导入自定义的filter模块-->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .condition a {
            display: inline-block;
            padding: 3px 5px;
            border: 1px solid #dddddd;
            margin: 5px;
            text-decoration: none;
        }
        .condition a.active{
            background-color: cadetblue;
        }
    </style>
</head>
<body>
    <h1>过滤条件</h1>
    <div class="condition">
        <div>
            <!--过滤全部文章类型-->
            {% filter_all arg_dict 'article_type_id'%}
            <!--过滤单个文章类型-->
            {% filter_article_type article_type_list arg_dict %}
        </div>

        <div>
            <!--过滤全部文章分类-->
            {% filter_all arg_dict 'category_id'%}
            <!--过滤单个文章分类-->
            {% filter_category_type catagory_list arg_dict %}
        </div>
    </div>

    <h1>查询结果</h1>
    <ul>
        {% for row in result %}
            <li>{{ row.id }}-{{ row.title }}</li>
        {% endfor %}
    </ul>
</body>
</html>
article.html

显示的效果图和上面的一模一样

四、文章分类放内存

  之前我们文章分类的数据是放在数据库的,那如果我们的文章分类是放在内存中,我们如何改进呐?

4.1、model的改进

说明:数据库的改进,我们增加choice选项,代替原来的外键

from django.db import models

class Category(models.Model):
    """
    文章分类表
    """
    caption = models.CharField(max_length=16)

class Article(models.Model):
    """
    文章表
    """
    title = models.CharField(max_length=32)
    content = models.CharField(max_length=255)
    category = models.ForeignKey(Category,on_delete=models.CASCADE)

    #把表改成内存级别的,因为这几个是不变的东西
    type_choice = (
        (1,'Python'),
        (2,'Openstack'),
        (3,'Linux'),
    )
    article_type_id = models.IntegerField(choices=type_choice)

4.2、article函数改进

说明:文章分类对象是直接从内存中去获取的,而不是重另外一张表中获取

from django.shortcuts import render
from app01 import models

def article(request,*args,**kwargs):
    condition = {}
    #如果显示全部的话,则显示所有文章
    for k,v in kwargs.items():
        kwargs[k] = int(v)
        if v == '0':
            pass
        else:
            condition[k] = v
    article_type_list = models.Article.type_choice  #article_type_list=((1, 'Python'), (2, 'Openstack'), (3, 'Linux'))
    catagory_list = models.Category.objects.all()
    result = models.Article.objects.filter(**condition)
    return render(request,'article.html',
                  {
                    'result':result,
                    'article_type_list':article_type_list, 
                    'catagory_list':catagory_list,  
                    'arg_dict':kwargs, 
                   }
                  )

4.3、filter模块中filter_article_type改进

说明:因为是一个article_type_list是一个数组类型的,所以获取row.id和row.caption,就会变成row[0],row[1]

@register.simple_tag
def filter_article_type(article_type_list,arg_dict):
    """
    过滤文章类型
    :param article_type_list:
    :param arg_dict:
    :return:
    """
    ret = list()
    for row in article_type_list:  #article_type_list=((1, 'Python'), (2, 'Openstack'), (3, 'Linux'))
        if row[0] == arg_dict['article_type_id']:
            temp = '<a class="active" href="/article-%s-%s.html">%s</a>'%(row[0],arg_dict['category_id'],row[1],)
        else:
            temp = '<a href="/article-%s-%s.html">%s</a>'%(row[0],arg_dict['category_id'],row[1],)
        ret.append(temp)

    return mark_safe(''.join(ret))

显示的效果图:

 

转载于:https://www.cnblogs.com/zhangqigao/articles/9055577.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值