产品列表,产品详情,产品创建和产品修改 - 4个页面
类别列表,类别详情,类别创建和类别修改 - 4个页面
文档列表,文档详情,文档创建和文件修改 - 4个页面
文档一般搜索和Ajax搜索 - 1个页面
项目需求
对于任何IT项目开发,能快速准确描述项目需求是一项技能。本教程中smartdoc对于文档搜索的需求如下, 我们稍后来看看如何实现。
用户可以根据标题,产品名字和代码来搜索相关文档
文档列表或其它页面上带有搜索框(见图1),用户输入关键词并按提交后,跳转到文档搜索页面,显示结果。
在文档搜索页面,用户输入关键词(不用按提交按钮), 实时显示搜索结果 - Ajax搜索(见图2)。
实时文档搜索页面
urls.py
我们需要设计两个urls, 一个负责接收用户输入的关键词q,在前端返回搜索结果。一个负责在后台接收实时变化的关键词q,并给前端提供json格式数据。
urlpatterns = [
#文档搜索
path('document/search/',views.document_search,name='document_search'),
# Ajax返回json数据
path('ajax/search/',views.doc_ajax_search,name='doc_ajax_search'),
]
views.py
我们需要编写两个视图方法对应两个urls。因为我们需要使用的搜索条件很多,所以我们调用了Q方法。document_search方法负责接收用户提交的关键词q,查询数据库并返回HTTP页面和搜索结果列表。doc_ajax_search实时接收用户数据的关键词q,并给前端返回一个包含搜索结果json格式的字典。
from.modelsimportProduct,Category,Document
fromdjango.db.modelsimportQ
fromdjango.httpimportJsonResponse,HttpResponse
fromdjango.views.decorators.csrfimportcsrf_exempt
importjson
importdatetime
defdocument_search(request):
q = request.GET.get('q', None)
ifq:
document_list = Document.objects.filter(Q(title__icontains=q) |
Q(product__name__icontains=q) |
Q(product__code__icontains=q))
context = {'document_list': document_list}
returnrender(request,'smartdoc/document_search.html',context)
returnrender(request,'smartdoc/document_search.html',)
defdoc_ajax_search(request):
q = request.GET.get('q', None)
ifq:
document_list = Document.objects.filter(Q(title__icontains=q) |
Q(product__name__icontains=q) |
Q(product__code__icontains=q))
data = []
fordocumentindocument_list:
data.append({"title": document.title,"product_name": document.product.name,
"category_name": document.category.name,
"format": document.doc_file.url.split('.')[-1].upper(),
"size":"{:.1f}KB".format(document.doc_file.size/1024),
"version": document.version_no,"date": document.mod_date,
"product_id": document.product.id,"id": document.id,
"url": document.doc_file.url,
})
json_data = json.dumps(data,cls=MyEncoder)
returnHttpResponse(json_data)
classMyEncoder(json.JSONEncoder):
defdefault(self,obj):
ifisinstance(obj,datetime.datetime):
returnobj.strftime('%Y-%m-%d')
elifisinstance(obj,datetime.date):
returnobj.strftime('%Y-%m-%d')
returnjson.JSONEncoder.default(self,obj)
由于Datetime类型数据无法被json序列化,所以我们必需定义MyEcoder,把日期转成我们想要的字符串格式。除了日期和时间外,还有很多Python类型数据不能直接转成json格式,比如单个的对象(object), 二进制(bytes), 方法(method), QuerySet(查询集), ValueQuerySet和集合(set)。Django自带的serializers也能解决一些数据Json序列化问题,但更强大的显然是Django Rest Framework,我们后面会专题介绍。
template
# smartdoc/document_search.html
模板逻辑如下所示:
当有{{ document_list }}时,直接显示搜索结果。
每当输入框元素#q里的值有变化时,将该值通过ajax发送到/smartdoc/ajax/search/。
后台/smartdoc/ajax/search/收到ajax请求后,返回json字典格式数据。
前端如果成功收到json数据,对其遍历,并显示在#id=result的元素里。
{% extends "smartdoc/base.html" %}
{% block content %}
搜索文档
{% csrf_token %}
class="input-group-btn">
class="glyphicon glyphicon-search">
{% endblock %}
{% block js %}
{% endblock %}
Ajax技术的关键在于后台是否能正确地返回json格式的数据,这和其它Web API是一个道理。我们是可以直接在浏览器中访问ajax对应的urls,看其能否提供json格式数据的,如下所示。里面的乱码是unicode格式的汉字,可以在前端正确显示的。
小结
本系列教程详细介绍了如何利用Django开发一个企业级应用smartdoc智能文档管理系统,并重点分析了如何控制和管理用户权限,以及实现Ajax快速搜索。全部代码如下,仅用于学习目的,希望对大家有所帮助。
https://github.com/shiyunbo/django-smartdoc
大江狗
2018.8.26
领取专属 10元无门槛券
私享最新 技术干货