Python基础(二十五)
一、组合搜索表
第一种:最简单的方式
models.py里面的设置:
from django.db import models # Create your models here. 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) #建立外键约束 article_type = models.ForeignKey(ArticleType)
urls.py里面的设置:
from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^article/',views.article), ]
app01/views.py里面的设置:
from django.shortcuts import render from app01 import models def article(request): result = models.Article.objects.all() return render(request,'article.html',{'result':result})
article.html里面的设置:
<h1>查询结果</h1> <ul> {% for row in result %} <li>{{ row.id }}-{{ row.title }}</li> {% endfor %} </ul>
查看结果(下面的数据需要提前去表里面创建一些好看效果):
第二种:我们让内容显示的更多一点
app01/views.py里面的设置:
from django.shortcuts import render from app01 import models def article(request,*args,**kwargs): article_type_list = models.ArticleType.objects.all() category_list = models.Category.objects.all() result = models.Article.objects.all() return render( request, 'article.html', { 'result':result, 'article_type_list':article_type_list, 'category_list':category_list })
article.html里面的设置:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>过滤条件</h1> <div> {% for row in article_type_list %} <a>{{ row.caption }}</a> {% endfor %} </div> <div> {% for row in category_list %} <a>{{ row.caption }}</a> {% endfor %} </div> <h1>查询结果</h1> <ul> {% for row in result %} <li>{{ row.id }}-{{ row.title }}</li> {% endfor %} </ul> </body> </html>
查看结果:
第三种:点击不同的过滤条件,url发生对应的跳转,并有颜色显示:
app01/views.py里面的设置:
from django.shortcuts import render # Create your views here. from app01 import models from django.urls import reverse def article(request,*args,**kwargs): print(kwargs) condition = {} for k,v in kwargs.items(): kwargs[k] = int(v) if v == '0': pass else: condition[k] = v article_type_list = models.ArticleType.objects.all() category_list = models.Category.objects.all() result = models.Article.objects.filter(**condition) return render( request, 'article.html', { 'result':result, 'article_type_list':article_type_list, 'category_list':category_list, 'arg_dict':kwargs })
article.html里面的设置:
<!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 ; } .condition a.active{ background-color: brown; } </style> </head> <body> <h1>过滤条件</h1> <div class="condition"> <div> {% 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 %} {% if row.id == arg_dict.article_type_id %} <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> {% 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 category_list %} {% if row.id == arg_dict.category_id %} <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>
显示结果:
第四种:通过函数实现,前端html页面不用写那么多代码:
app01/templatetags/filter.py的设置:
from django import template from django.utils.safestring import mark_safe register = template.Library() @register.simple_tag def filter_all(arg_dict,k): if k == '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'] 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): ret = [] 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(category_list,arg_dict): ret = [] for row in category_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))
article.html的页面设置:
{% load filter %} <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> <style> .condition a{ display: inline-block; padding: 3px 5px; border: 1px solid #dddddd; margin: 5px ; } .condition a.active{ background-color: brown; } </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 category_list arg_dict %} </div> </div> <h1>查询结果</h1> <ul> {% for row in result %} <li>{{ row.id }}-{{ row.title }}</li> {% endfor %} </ul> </body> </html>
查看结果:
二、JSONP:
jsonp是一种请求方式,用来解决一些棘手的问题。
先要提一下下面的get方式:
Import requests
request.get(‘http://www.baidu.com’) #往百度发一个get请求
request.post(‘http://www.baidu.com’) #往百度发一个post请求
下面是使用方式:
import requests def req(request): response = requests.get('http://weatherapi.market.xiaomi.com/wtr-v2/weather?cityId=101121301') print(response.text) #所有的文本内容 print(response.cookies) #所有的cookies print(response.headers) #所有的响应头
下面是一个request.get的例子:
urls.py的设置
from app02 import views as a2 urlpatterns = [ url(r'^req/',a2.req), ]
app02/views设置:
import requests def req(request): response = requests.get('http://weatherapi.market.xiaomi.com/wtr-v2/weather?cityId=101121301') response.encoding = 'utf-8' #表示让字节用utf8编码编成字符串 #print(response.content) #字节类型 print(response.text) #字符串类型的 return render(request,'req.html',{'result':response.text})
html页面req.html设置:
<body>
{{ result }}
</body>
结果显示:
现在这种模式是用户浏览器发送数据到我们的服务器端,然后服务器端再向天气服务器获取数据然后服务器端再把数据返回给浏览器。
第二个例子:我们用这个形式让浏览器直接向天气网站发请求获取数据:
下面是html里面的设置:
<body> <h1>后台获取的结果</h1> {{ result }} <h1>js直接获取结果</h1> <input type="button" value="获取数据" onclick="getContent();" /> <div id="container"></div> <script> function getContent(){ var xhr = new XMLHttpRequest(); #创建一个对象 xhr.open('GET','http://weatherapi.market.xiaomi.com/wtr-v2/weather?cityId=101121301'); #以get方式打开,并传递一个URL xhr.onreadystatechange = function(){ #发送完成后等于一个回调函数 console.log(xhr.responseText) #拿到返回的文本信息 } xhr.send(); #发送消息 </body>
查看结果:
浏览器会出现下面的问题:
XMLHttpRequest cannot load http://weatherapi.market.xiaomi.com/wtr-v2/weather?cityId=101121301. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
其实我们的请求已经发送到了Html页面里面设置的URL,但是浏览器具有同源策略,如果直接去别的域名去请求数据,浏览器直接就会拒绝掉返回的数据。
这时候我们就要解决浏览器阻止Ajax的请求,绕过去,浏览器无法阻止<script src='...'></script>,返回的数据必须是js格式。
并且jsonp只能发get请求。遵循统一规则callback。
第三个例子:
下面是正确的取值方式:
req.html:
<body> <h1>后台获取的结果</h1> {{ result }} <h1>js直接获取结果</h1> <input type="button" value="获取数据" onclick="getContent();" /> <div id="container"></div> <script> function getContent(){ var tag = document.createElement('script'); #创建script标签 tag.src = 'http://www.jxntv.cn/data/jmd-jxtv2.html?callback=list&_=1454376870403'; document.head.appendChild(tag); #添加tag document.head.removeChild(tag); #删除tag } function list(arg){ #获取js数据 console.log(arg); } </script> </body>
查看结果:
第四个例子用jquery方式,这也是比较常用的方式:
<input type="button" value="获取数据" onclick="getContent();" /> <div id="container"></div> <script src="/static/jquery-1.8.2.js"></script> <script> function getContent(){ $.ajax({ url: 'http://www.jxntv.cn/data/jmd-jxtv2.html', type: 'POST', dataType: 'jsonp', jsonp: 'callback', jsonpCallback: 'list' } ) } function list(arg){ console.log(arg); } </script>
查看结果: