Django实现组合搜索

一、实现方法

1.纯模板语言实现

2.自定义simpletag实现(本质是简化了纯模板语言的判断)

二、基本原理

原理都是通过django路由系统,匹配url筛选条件,将筛选条件作为数据库查询结果,返回给前端。

例如:路由系统中的url格式是这样:

url(r'^article-(?P<article_type_id>\d+)-(?P<category_id>\d+).html',views.filter)

其中article_type_id和category_id和数据库中字段是相对应的,此时当一个url为article-1-2.html时候,后台处理函数的参数将是一个字典{'article_type_id': 1, 'category_id': 1},然后将该条件作为数据库查询条件,最后得出结果返回给前端

三、代码样例

方法1:纯模板语言实现

urls.py

#!/usr/bin/env python3
#_*_ coding:utf-8 _*_
#Author:wd
from django.conf.urls import url

from . import views
urlpatterns = [
    url(r'^$',views.index),
    url(r'^article-(?P<article_type_id>\d+)-(?P<category_id>\d+).html',views.filter),
]

models.py

from django.db import models

class Category(models.Model):
    caption=models.CharField(max_length=64)

class Article_type(models.Model):
    caption=models.CharField(max_length=64)

class Article(models.Model):
    title=models.CharField(max_length=64)
    content=models.CharField(max_length=256)
    category=models.ForeignKey(to='Category')
    article_type=models.ForeignKey(to='Article_type'

views.py

def filter(request,*args,**kwargs):
    if request.method=="GET":
        condition={}
        for k,v in kwargs.items():
                    kwargs[k]=int(v)  #模板if判断row.id是数字,所以这里需要转换
                    if v=="0":#当条件为0代表所选的是全部,那么就不必要加入到过滤条件中
                        pass
                    else:
                        condition[k]=int(v)
        aritcle=models.Article.objects.filter(**condition)
        aritcle_type=models.Article_type.objects.all()
        aritcle_category=models.Category.objects.all()
        return  render(request,'search.html',{
            'aritcle':aritcle,
            'article_type':aritcle_type,
            'article_category':aritcle_category,
            'article_arg':kwargs,#将当前的筛选条件传递给html
        })

html模板

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .container a{
            display: inline-block;
            padding: 3px 5px;
            margin: 5px;
            border: 1px solid #dddddd ;
        }
        .active{
            background-color: rebeccapurple;

        }
    </style>
</head>
<body>
<h1>搜索条件</h1>
<div class="container">
    {% if article_arg.article_type_id == 0 %}
        <a class="active" href="/cmdb/article-0-{{ article_arg.category_id }}.html">全部</a>
    {% else %}
         <a  href="/cmdb/article-0-{{ article_arg.category_id }}.html">全部</a>
    {% endif %}
    {% for row in article_type %}
        {% if row.id == article_arg.article_type_id %}
            <a class="active" href="/cmdb/article-{{ row.id }}-{{ article_arg.category_id }}.html">{{ row.caption }}</a>
        {% else %}
            <a  href="/cmdb/article-{{ row.id }}-{{ article_arg.category_id }}.html">{{ row.caption }}</a>
        {% endif %}
    {% endfor %}
</div>
<div class="container">
     {% if article_arg.category_id == 0 %}
        <a class="active" href="/cmdb/article-{{ article_arg.article_type_id }}-0.html">全部</a>
    {% else %}
          <a  href="/cmdb/article-{{ article_arg.article_type_id }}-0.html">全部</a>
    {% endif %}
    {% for row in article_category %}
        {% if row.id == article_arg.category_id %}
        <a class="active" href="/cmdb/article-{{ article_arg.article_type_id }}-{{ row.id }}.html">{{ row.caption }}</a>
        {% else %}
        <a href="/cmdb/article-{{ article_arg.article_type_id }}-{{ row.id }}.html">{{ row.caption }}</a>
        {% endif %}
    {% endfor %}
</div>
<h1>查询结果</h1>
<div>
    {% for row in aritcle %}
        <div>{{ row.id }}-{{ row.title }}</div>
    {% endfor %}
</div>
</body>
</html>

方法二:使用simpletag实现

定义simpletag,参考博客Django基础篇

myfilter.py

#!/usr/bin/env python3
#_*_ coding:utf-8 _*_
#Author:wd
from django import template
from django.utils.safestring import mark_safe

register=template.Library()
@register.simple_tag
def filter_all(article_arg,condition):
    '''
    处理条件为全部
    :param article_arg: 当前url字典:如{'article_type_id': 1, 'category_id': 1}
    :param condition: 要处理的条件,如article_type_id,用于区分当前处理选择了那个全部
    :return: 返回下面页面形式
    {% if article_arg.article_type_id == 0 %}
        <a class="active" href="/cmdb/article-0-{{ article_arg.category_id }}.html">全部</a>
    {% else %}
         <a  href="/cmdb/article-0-{{ article_arg.category_id }}.html">全部</a>
    {% endif %}
    {% for row in article_type %}
        {% if row.id == article_arg.article_type_id %}
            <a class="active" href="/cmdb/article-{{ row.id }}-{{ article_arg.category_id }}.html">{{ row.caption }}</a>
        {% else %}
            <a  href="/cmdb/article-{{ row.id }}-{{ article_arg.category_id }}.html">{{ row.caption }}</a>
        {% endif %}
    {% endfor %}
    '''
    if condition=='article_type_id':
        if article_arg[condition]==0:
            print(article_arg['category_id'])
            res= '<a class ="active" href="/cmdb/article-0-%s.html">全部</a>' % article_arg['category_id']
        else:
            res = '<a href="/cmdb/article-0-%s.html">全部</a>' % article_arg['category_id']
        return mark_safe(res)
    elif condition=='category_id':
        if article_arg['category_id']==0:
            res = '<a class ="active" href="/cmdb/article-%s-0.html">全部</a>' % article_arg['article_type_id']
        else:
            res = '<a href="/cmdb/article-%s-0.html">全部</a>' % article_arg['article_type_id']
        return mark_safe(res)

@register.simple_tag
def filter_type(article_type,article_arg):
    '''
   :param article_type: article_type对象
   :param article_arg: 当前url字典
   :return: 
   {% for row in article_type %}
        {% if row.id == article_arg.article_type_id %}
            <a class="active" href="/cmdb/article-{{ row.id }}-{{ article_arg.category_id }}.html">{{ row.caption }}</a>
        {% else %}
            <a  href="/cmdb/article-{{ row.id }}-{{ article_arg.category_id }}.html">{{ row.caption }}</a>
        {% endif %}
    {% endfor %}
     '''
    res=[]
    for row in article_type:
        if row.id== article_arg['article_type_id']:
           temp='<a class="active" href="/cmdb/article-%s-%s.html">%s</a>' %(row.id,article_arg['category_id'],row.caption)
        else:
            temp = '<a  href="/cmdb/article-%s-%s.html">%s</a>' % (row.id, article_arg['category_id'],row.caption)
        res.append(temp)
    return mark_safe("".join(res))

@register.simple_tag
def filter_category(article_category,article_arg):
    '''
   :param article_type: article_category对象
   :param article_arg: 当前url字典
   :return: 
   {% for row in article_category %}
        {% if row.id == article_arg.category_id %}
        <a class="active" href="/cmdb/article-{{ article_arg.article_type_id }}-{{ row.id }}.html">{{ row.caption }}</a>
        {% else %}
        <a href="/cmdb/article-{{ article_arg.article_type_id }}-{{ row.id }}.html">{{ row.caption }}</a>
        {% endif %}
    {% endfor %}
     '''
    res=[]
    for row in article_category:
        if row.id== article_arg['category_id']:
           temp='<a class="active" href="/cmdb/article-%s-%s.html">%s</a>' %(article_arg['article_type_id'],row.id,row.caption)
        else:
            temp = '<a  href="/cmdb/article-%s-%s.html">%s</a>' % (article_arg['article_type_id'],row.id,row.caption)
        res.append(temp)
    return mark_safe("".join(res))

html模板

{% load myfilter %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .container a{
            display: inline-block;
            padding: 3px 5px;
            margin: 5px;
            border: 1px solid #dddddd ;
        }
        .active{
            background-color: rebeccapurple;

        }
    </style>
</head>
<body>
<h1>搜索条件</h1>
<div class="container">
    {% filter_all article_arg 'article_type_id' %}
    {% filter_type article_type article_arg %}
</div>
<div class="container">
    {% filter_all article_arg 'category_id' %}
    {% filter_category article_category article_arg %}
</div>
<h1>查询结果</h1>
<div>
    {% for row in aritcle %}
        <div>{{ row.id }}-{{ row.title }}</div>
    {% endfor %}
</div>
</body>
</html>

ps附上简图:

四、其他变化

在如上的示例中,我们的过滤条件是从数据库中拿到,有时候我们定义的时候使用的是静态字段,此时组合搜索会稍微修改。

1.model定义

class Article(models.Model):
    title=models.CharField(max_length=64)
    content=models.CharField(max_length=256)
    category=models.ForeignKey(to='Category')
    article_type=(    #使用静态字段放入内存
        (1,'linux'),
        (2,'python'),
        (3,'go'),
    )

2.处理函数变化

###获取####
aritcle_type=models.Article.article_type#直接获取类的静态字段

3.simpletag相应改变

###由于我们传递的元祖,所以取值使用元祖方式
article_type[0]# 筛选条件id
article_type[1]# 筛选条件名称

 

转载于:https://www.cnblogs.com/wdliu/p/8331375.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 当然可以,下面是一个简单的 Django 搜索功能的示例代码: 首先,在 Django 中创建一个模型,例如“Book”模型: ```python from django.db import models class Book(models.Model): title = models.CharField(max_length=100) author = models.CharField(max_length=100) publication_date = models.DateField() def __str__(self): return self.title ``` 然后,在 Django 中创建一个搜索视图: ```python from django.shortcuts import render from django.db.models import Q from .models import Book def search(request): query = request.GET.get('q') results = Book.objects.filter( Q(title__icontains=query) | Q(author__icontains=query) ) return render(request, 'search_results.html', {'results': results}) ``` 在这个视图中,我们首先获取用户输入的查询字符串,然后使用 Django 的 Q 对象执行一个 OR 查询,以查找书籍标题或作者中包含查询字符串的所有书籍。最后,我们将结果传递给一个名为“search_results.html”的模板,以呈现搜索结果。 最后,在 Django 中创建一个搜索表单,例如: ```html <form method="GET" action="{% url 'search' %}"> <input type="text" name="q" placeholder="Search..."> <button type="submit">Search</button> </form> ``` 这将创建一个简单的搜索表单,其中用户可以输入查询字符串并提交表单以执行搜索。 ### 回答2: 要实现搜索功能,可以使用Django提供的QuerySet对象和Q对象进行查询操作。首先在视图函数中获取用户输入的搜索关键字。然后使用Q对象创建查询条件,包括搜索关键字在适当的字段中出现的要求。最后通过调用filter函数对查询条件进行过滤,获取满足条件的对象。 具体的代码示例如下: ```python from django.shortcuts import render from django.db.models import Q from .models import MyModel def search(request): keyword = request.GET.get('keyword') objects = MyModel.objects.filter( Q(field1__icontains=keyword) | # 匹配 field1 中包含 keyword 的对象 Q(field2__icontains=keyword) # 匹配 field2 中包含 keyword 的对象 ) return render(request, 'search_result.html', {'objects': objects}) ``` 上述代码中,假设有一个名为MyModel的模型类,其中包含field1和field2两个字段。在视图函数search中,通过request.GET.get('keyword')获取用户在搜索框中输入的关键字。然后使用filter函数对MyModel对象进行过滤,通过Q对象创建查询条件。下面的示例中使用icontains函数进行不区分大小写的模糊查询,你也可以根据需要选择其他查询方式。 最后将满足条件的对象传递给模板,并在模板中展示搜索结果。在模板中可以使用for循环遍历objects对象,展示对象的相关信息。 希望以上回答对你有帮助! ### 回答3: 在Django实现搜索功能需要以下几个步骤: 1. 创建一个模型类,用于表示你要搜索的数据对象。例如,如果你要搜索文章的标题和内容,可以定义一个Article模型类,并定义相应的字段。 ```python from django.db import models class Article(models.Model): title = models.CharField(max_length=100) content = models.TextField() # 其他字段... ``` 2. 创建一个搜索表单,用于接收用户的搜索关键字。可以使用Django的Forms模块来实现。例如,可以创建一个SearchForm表单类,其中包含一个CharField用于接收搜索关键字。 ```python from django import forms class SearchForm(forms.Form): keyword = forms.CharField(max_length=100) # 其他字段... ``` 3. 创建一个搜索视图函数,用于处理用户的搜索请求。在视图函数中,首先根据用户提交的搜索关键字过滤模型数据,然后将过滤后的结果传递给模板渲染。 ```python from django.shortcuts import render from .forms import SearchForm from .models import Article def search(request): form = SearchForm(request.GET) if form.is_valid(): keyword = form.cleaned_data['keyword'] results = Article.objects.filter(title__contains=keyword) | Article.objects.filter(content__contains=keyword) else: results = None return render(request, 'search.html', {'form': form, 'results': results}) ``` 4. 创建一个模板文件,用于展示搜索结果以及搜索表单。例如,可以创建一个search.html模板文件。 ```html <form method="get" action="{% url 'search' %}"> {{ form }} <input type="submit" value="搜索"> </form> {% if results %} <ul> {% for article in results %} <li>{{ article.title }}</li> {% empty %} <li>没有找到匹配的结果。</li> {% endfor %} </ul> {% endif %} ``` 上述代码实现了一个基本的搜索功能,用户可以在表单中输入关键字,点击搜索按钮后,系统将根据关键字查询相关的文章,并在页面上展示搜索结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值