django model练习2 基于model的Q和ajax 实现搜索多条件的案例

1 项目准备参考我的另一篇博客

http://www.cnblogs.com/liujianzuo888/articles/5798658.html

Django model 练习

 

本案例小点总结:

前端
	+ 下拉框(书名) <input name='name' />   python之路,python红宝书
	- 下拉框(图书类型)<input name='book_type__caption' /> 文学
	- 下拉框(价格)<input name='price' />    59,77                                 搜索框 
	
	$.each()
	dict = {
		"name": [python之路,python红宝书],
		"book_type__caption": [文学,],
		"price": [11,2]
	}
	==>列表序列化
	$.ajax({
		
		data: dict
		
		success: function(arg){
			
			数据,生成HTML标签, document.createElement(...)
			添加指定位置
		}
	})

后端
	request.POST.get('name')
	request.POST.get('book_type__caption')
	request.POST.get('price')
	con = Q()
	q1 = Q()
	[python之路,python红宝书    或者
	q2 = Q()
	[文学,],    或者
	,,,
	con.(q1,q2,q3)
	result = model.Book.objects.filter(con).values()
	return HttpResponse(result序列化)

  

 

2 model类的建表

class Author(models.Model):
    name = models.CharField(max_length=20)
    age = models.IntegerField()

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

class Book(models.Model):
    name = models.CharField(max_length=64)
    pages = models.IntegerField()
    price = models.DecimalField(max_digits=10, decimal_places=2)
    pubdate = models.DateField()

    authors = models.ManyToManyField(Author)
    book_type = models.ForeignKey(BookType)

 生成测试数据 

 

models.Book.objects.create(name='文艺复兴',pages='100',price='40',pubdate='1992-11-2',book_type_id='1')
    models.Book.objects.create(name='解密',pages='80',price='10', pubdate='2016-6-10',book_type_id='1')
    models.Book.objects.create(name='刀锋',pages='50',price='3', pubdate='2014-02-16',book_type_id='1')
    models.Book.objects.create(name='查令十字路84号',pages='260',price='40',pubdate='1999-10-12',book_type_id='3')
    models.Book.objects.create(name='红楼',pages='1000',price='500', pubdate='1760-1-1',book_type_id='3')
    models.Book.objects.create(name='将夜',pages='2000',price='300', pubdate='2010-3-3',book_type_id='2')
    models.Book.objects.create(name='mysql从删库到跑路',pages='20',price='10',pubdate='1998-9-2',book_type_id='2')
    models.Book.objects.create(name='马克思主义',pages='50',price='100',pubdate='1937-3-3',book_type_id='2')
   

 

 

  

3 页面搜索框 

indexhtml

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .left{
            float: left;
        }
        .clearfix:after{
            content: '.';
            clear: both;
            display: block;
            visibility: hidden;
            height: 0;
        }
    </style>
</head>
<body>
    <div class="condition">
        <div class="item clearfix">
            <div class="icon left" onclick="AddCondition(this);">+</div>
            <div class="left">
                <select onchange="ChangeName(this);">
                    <option value="name">书名</option>
                    <option value="book_type__caption">图书类型</option>
                    <option value="price">价格</option>
                    <option value="pages">页数</option>
                </select>
            </div>
            <div class="left"><input type="text" name="name" /></div>
        </div>
    </div>
    <div>
        <input type="button" onclick="Search();" value="搜索" />
    </div>

    <div class="container">

    </div>



    <script src="/static/jquery-1.12.4.js"></script>
    <script>
        function  AddCondition(ths) {
            var new_tag = $(ths).parent().clone();
            new_tag.find('.icon').text('-');
            new_tag.find('.icon').attr('onclick', 'RemoveCondition(this);');

            $(ths).parent().parent().append(new_tag);
        }
        function  RemoveCondition(ths) {
            $(ths).parent().remove();
        }
        function ChangeName(ths) {
            var v = $(ths).val();
            $(ths).parent().next().find('input').attr('name',v);
        }
        function Search() {
            var post_data_dict = {};

            // 获取所有input的内容,提交数据
            $('.condition input').each(function () {
                // console.log($(this)[0])
                var n = $(this).attr('name');
                var v = $(this).val();
                var v_list = v.split('');
                post_data_dict[n] = v_list;
            });
            console.log(post_data_dict);
            var post_data_str = JSON.stringify(post_data_dict);
            $.ajax({
                url: '/index/',
                type: 'POST',
                data: { 'post_data': post_data_str},
                dataType: 'json',
                success: function (arg) {
                    // 字符串 "<table>" +
                    if(arg.status){
                        var table = document.createElement('table');
                        table.setAttribute('border',1);
                        // [{,name,pubdate,price,caption},]
                        $.each(arg.data, function(k,v){
                            var tr = document.createElement('tr');

                            var td1 = document.createElement('td');
                            td1.innerText = v['name'];
                            var td2 = document.createElement('td');
                            td2.innerText = v['price'];
                            var td3 = document.createElement('td');
                            td3.innerText = v['book_type__caption'];
                            var td4 = document.createElement('td');
                            td4.innerText = v['pubdate'];
                            tr.appendChild(td1);
                            tr.appendChild(td2);
                            tr.appendChild(td3);
                            tr.appendChild(td4);

                            table.appendChild(tr);
                        });

                        $('.container').empty();
                        $('.container').append(table);
                    }else{
                        alert(arg.message);
                    }

                }

            })
        }
    </script>
</body>
</html>
index.html

分开解释 用到的知识点

1 js

function  AddCondition(ths) {
            var new_tag = $(ths).parent().clone();
            new_tag.find('.icon').text('-');
            new_tag.find('.icon').attr('onclick', 'RemoveCondition(this);');

            $(ths).parent().parent().append(new_tag);
        }
        function  RemoveCondition(ths) {
            $(ths).parent().remove();
        }
克隆搜索框 删除搜索框

2 子div都飘撑起父亲div

.clearfix:after{
            content: '.';
            clear: both;
            display: block;
            visibility: hidden;
            height: 0;
        }

3 搜索:条件切片 发送ajax

function Search() {
            var post_data_dict = {};

            // 获取所有input的内容,提交数据
            $('.condition input').each(function () {
                // console.log($(this)[0])
                var n = $(this).attr('name');
                var v = $(this).val();
                var v_list = v.split('');
                post_data_dict[n] = v_list;
            });
            console.log(post_data_dict);
            var post_data_str = JSON.stringify(post_data_dict);
            $.ajax({
                url: '/index/',
                type: 'POST',
                data: { 'post_data': post_data_str},
                dataType: 'json',
                success: function (arg) {
                    // 字符串 "<table>" +
                    if(arg.status){
                        var table = document.createElement('table');
                        table.setAttribute('border',1);
                        // [{,name,pubdate,price,caption},]
                        $.each(arg.data, function(k,v){
                            var tr = document.createElement('tr');

                            var td1 = document.createElement('td');
                            td1.innerText = v['name'];
                            var td2 = document.createElement('td');
                            td2.innerText = v['price'];
                            var td3 = document.createElement('td');
                            td3.innerText = v['book_type__caption'];
                            var td4 = document.createElement('td');
                            td4.innerText = v['pubdate'];
                            tr.appendChild(td1);
                            tr.appendChild(td2);
                            tr.appendChild(td3);
                            tr.appendChild(td4);

                            table.appendChild(tr);
                        });

                        $('.container').empty();
                        $('.container').append(table);
                    }else{
                        alert(arg.message);
                    }

                }

            })
        }
View Code

 4 ajax 提交的url一定要加/

  发送ajax提交时候的url的路径一定要加/

 $.ajax({
                url: '/index/',
                type: 'POST',
})

 

 

 

4 后端的 view文件 

from django.shortcuts import render,HttpResponse
from app01 import models
# Create your views here.
import json
def test(request):
    # models.BookType.objects.create(caption='技术')
    # models.BookType.objects.create(caption='文学')
    # models.BookType.objects.create(caption='动漫')
    # models.BookType.objects.create(caption='男人装')

    # models.Book.objects.create(name='文艺复兴',pages='100',price='40',pubdate='1992-11-2',book_type_id='1')
    # models.Book.objects.create(name='解密',pages='80',price='10', pubdate='2016-6-10',book_type_id='2')
    # models.Book.objects.create(name='刀锋',pages='50',price='3', pubdate='2014-02-16',book_type_id='2')
    # models.Book.objects.create(name='查令十字路84号',pages='260',price='40',pubdate='1999-10-12',book_type_id='3')
    # models.Book.objects.create(name='红楼',pages='1000',price='500', pubdate='1760-1-1',book_type_id='3')
    # models.Book.objects.create(name='将夜',pages='2000',price='300', pubdate='2010-3-3',book_type_id='1')
    # models.Book.objects.create(name='mysql从删库到跑路',pages='20',price='10',pubdate='1998-9-2',book_type_id='4')
    # models.Book.objects.create(name='马克思主义',pages='50',price='100',pubdate='1937-3-3',book_type_id='2')

    return HttpResponse('ok')

import json
from datetime import date
from datetime import datetime
from decimal import Decimal
class JsonCustomEncoder(json.JSONEncoder): # 序列化时候json处理不了的我们需要自己做转换为json可以转换的数据类型

    def default(self, field):

        if isinstance(field, datetime):  #如果字段是时间类型
            return field.strftime('%Y-%m-%d %H:%M:%S')
        elif isinstance(field, date): # 
            return field.strftime('%Y-%m-%d')
        elif isinstance(field, Decimal): #如果是小数类型
            return str(field)
        else:
            return json.JSONEncoder.default(self, field)

def index(request):
    if request.method == 'POST':
        ret = {'status': False, 'message': '', 'data':None}
        try:
            post_data = request.POST.get('post_data',None)
            post_data_dict = json.loads(post_data)
            print(post_data_dict)
            # {'name': ['11', 'sdf'],'price': ['11', 'sdf']}
            # 构造搜索条件
            from django.db.models import Q
            con = Q()
            for k,v in post_data_dict.items():
                q = Q()
                q.connector = 'OR'
                for item in v:
                    q.children.append((k, item))
                con.add(q, 'AND')
            # django两种 序列化数据返回前端的方法
            #1 serialize 但是如果是数据的外键字段不会自动查询只会放回字典表id
            """  
            ret = models.Book.objects.filter(con)
            print(ret) # queryset,[对象]

            from django.core import serializers
            data = serializers.serialize("json", ret)
            print(type(data),data)
            # 字符串
            """
            # 通过json方式,这种事数据类型没有特殊的,json只能列表 字典 字符串
            """
            #ret = models.Book.objects.filter(con).values('name','book_type__caption')
            ret = models.Book.objects.filter(con).values_list('name', 'book_type__caption')
            print(ret,type(ret))
            li = list(ret)
            data = json.dumps(li)
            print(data,type(data))
            """
            result = models.Book.objects.filter(con).values('name','price','pubdate','book_type__caption')
            # ret = models.Book.objects.filter(con).values_list('name', 'book_type__caption')
            li = list(result)
            ret['status'] = True
            ret['data'] = li
        except Exception as e:
            ret['message'] = str(e)
            
        # 如果想让json也能处理decimal date类型的数据就需要自己写一个类处理 cls接收 会一个个循环ret的去处理。
        ret_str = json.dumps(ret, cls=JsonCustomEncoder) #
        return HttpResponse(ret_str)
    return render(request, 'index.html')


def test(request):

    # models.Book.objects.create(name='文艺复兴',pages='100',price='40',pubdate='1992-11-2',book_type_id='1')
    # models.Book.objects.create(name='解密',pages='80',price='10', pubdate='2016-6-10',book_type_id='1')
    # models.Book.objects.create(name='刀锋',pages='50',price='3', pubdate='2014-02-16',book_type_id='1')
    # models.Book.objects.create(name='查令十字路84号',pages='260',price='40',pubdate='1999-10-12',book_type_id='3')
    # models.Book.objects.create(name='红楼',pages='1000',price='500', pubdate='1760-1-1',book_type_id='3')
    # models.Book.objects.create(name='将夜',pages='2000',price='300', pubdate='2010-3-3',book_type_id='2')
    # models.Book.objects.create(name='mysql从删库到跑路',pages='20',price='10',pubdate='1998-9-2',book_type_id='2')
    # models.Book.objects.create(name='马克思主义',pages='50',price='100',pubdate='1937-3-3',book_type_id='2')
    return  render(request,"test.html")
view.py

 

解释用到的知识点

 1  返回ajax 的序列化问题

  django 返回前端ajax的数据序列化 

 

2 model 的Q应用

# {'name': ['11', 'sdf'],'price': ['11', 'sdf']}
            # 构造搜索条件
            from django.db.models import Q
            con = Q()
            for k,v in post_data_dict.items():
                q = Q()
                q.connector = 'OR'
                for item in v:
                    q.children.append((k, item))
                con.add(q, 'AND')
result = models.Book.objects.filter(con).values('name','price','pubdate','book_type__caption')

li = list(result)

  

 

5 前端ajax success收到数据后的处理注意点

标签操作

a. 创建标签

// 方式一  创建的方式
var tag = document.createElement('a')
tag.innerText = "wupeiqi"
tag.className = "c1"
tag.href = "http://www.cnblogs.com/wupeiqi"
  
// 方式二 字符串拼接
var tag = "<a class='c1' href='http://www.cnblogs.com/wupeiqi'>wupeiqi</a>"

 

b.操作标签

// 方式一 insertAdjacentHTML
var obj = "<input type='text' />";
xxx.insertAdjacentHTML("beforeEnd",obj);
xxx.insertAdjacentElement('afterBegin',document.createElement('p'))
  
//注意:第一个参数只能是'beforeBegin'、 'afterBegin'、 'beforeEnd'、 'afterEnd'
  
// 方式二 标签添加子标签 创建<p>添加<a>
var tag = document.createElement('a')
xxx.appendChild(tag) // 为xxx标签添加子标签
xxx.insertBefore(tag,xxx[1])

  

success: function (arg) {
                    // 字符串 "<table>" +
                    if(arg.status){
                        var table = document.createElement('table');
                        table.setAttribute('border',1);
                        // [{,name,pubdate,price,caption},]
                        $.each(arg.data, function(k,v){
                            var tr = document.createElement('tr');

                            var td1 = document.createElement('td');
                            td1.innerText = v['name'];
                            var td2 = document.createElement('td');
                            td2.innerText = v['price'];
                            var td3 = document.createElement('td');
                            td3.innerText = v['book_type__caption'];
                            var td4 = document.createElement('td');
                            td4.innerText = v['pubdate'];
                            tr.appendChild(td1);
                            tr.appendChild(td2);
                            tr.appendChild(td3);
                            tr.appendChild(td4);

                            table.appendChild(tr);
                        });

                        $('.container').empty();
                        $('.container').append(table);
                    }else{
                        alert(arg.message);
                    }

                }
success

 

 

 

posted @ 2016-08-25 16:42  众里寻,阑珊处  阅读(364)  评论(0编辑  收藏  举报
返回顶部