django queryset 去重 .distinct()说明


Posted in Python onMay 19, 2020

我就废话不多说了,大家还是直接看代码吧!

contacts = ExternalContacts.objects.filter(MobileKey=mobile_obj)
    house = House.objects.none()
    for contact in contacts:
      house = house | contact.house_set.all()
    return house.distinct()

合并出来的queryset,再去重。

补充知识:Python——深入理解urllib、urllib2及requests(requests不建议使用?)

Python 是一种面向对象、解释型计算机程序设计语言,由Guido van Rossum于1989年底发明,第一个公开发行版发行于1991年,Python 源代码同样遵循 GPL(GNU General Public License)协议[1] 。Python语法简洁而清晰,具有丰富和强大的类库。

urllib and urllib2 区别

urllib和urllib2模块都做与请求URL相关的操作,但他们提供不同的功能。

urllib2.urlopen accepts an instance of the Request class or a url, (whereas urllib.urlopen only accepts a url 中文意思就是:urllib2.urlopen可以接受一个Request对象或者url,(在接受Request对象时候,并以此可以来设置一个URL 的headers),urllib.urlopen只接收一个url

urllib 有urlencode,urllib2没有,这也是为什么总是urllib,urllib2常会一起使用的原因

r = Request(url='http://www.mysite.com')
r.add_header('User-Agent', 'awesome fetcher')
r.add_data(urllib.urlencode({'foo': 'bar'})
response = urllib2.urlopen(r)   #post method

urllib 模块

I. urlencode不能直接处理unicode对象,所以如果是unicode,需要先编码,有unicode转到utf8,举例:

urllib.urlencode (u'bl'.encode('utf-8'))

II. 示例

import urllib    #sohu 手机主页
 url = 'http://m.sohu.com/?v=3&_once_=000025_v2tov3&_smuid=\
    ICvXXapq5EfTpQTVq6Tpz'
 resp = urllib.urlopen(url)
 page = resp.read()
 f = open('./urllib_index.html', 'w')
 f.write(page)
 print dir(resp)

结果:

['doc', 'init', 'iter', 'module', 'repr', 'close', 'code', 'fileno', 'fp', 'getcode', 'geturl', 'headers', 'info', 'next', 'read', 'readline', 'readlines', 'url']

print resp.getcode(), resp.geturl(), resp.info(), resp.headers, resp.url
#resp.url和resp.geturl()结果一样

III. 编解码示例 urllib.quote和urllib.urlencode都是编码,但用法不一样

s = urllib.quote('This is python') #编码 
   print 'quote:\t'+s  #空格用%20替代 
   s_un = urllib.unquote(s)  #解码 
   print 'unquote:\t'+s_un 
   s_plus = urllib.quote_plus('This is python') #编码 
   print 'quote_plus:\t'+s_plus      #空格用+替代 
   s_unplus = urllib.unquote_plus(s_plus)    #解码 
   print 's_unplus:\t'+s_unplus 
   s_dict = {'name': 'dkf', 'pass': '1234'} 
   s_encode = urllib.urlencode(s_dict)  #编码字典转换成url参数 
   print 's_encode:\t'+s_encode

结果:

quote: This%20is%20python
 unquote:  This is python
 quote_plus:  This+is+python
 s_unplus: This is python
 s_encode: name=dkf&pass=1234

IV. urlretrieve() urlretrieve多数适用单纯的只下载的功能或者显示下载的进度等

url = 'http://m.sohu.com/?v=3&_once_=000025_v2tov3&_\
       smuid=ICvXXapq5EfTpQTVq6Tpz'
urllib.urlretrieve(url, './retrieve_index.html')

 #直接把url链接网页内容下载到retrieve_index.html里了,适用于单纯的下载的功能。
 #urllib.urlretrieve(url, local_name, method)

urllib2

I. urllib2模块定义的函数和类用来获取URL(主要是HTTP的),他提供一些复杂的接口用于处理: 基本认证,重定向,Cookies等。

II. 常用方法和类 II.1 urllib2.urlopen(url[, data][, timeout]) #传url时候,用法同urllib里的urlopen

II.1.1 它打开URL网址,url参数可以是一个字符串url或者是一个Request对象。可选的参数timeout,阻塞操作以秒为单位,如尝试连接(如果没 有指定,将使用设置的全局默认timeout值)。实际上这仅适用于HTTP,HTTPS和FTP连接。

url = 'http://m.sohu.com/?v=3&_once_=000025_v2tov3&_\
smuid=ICvXXapq5EfTpQTVq6Tpz'

resp = urllib2.urlopen(url)87   page = resp.read()

II.1.2 urlopen方法也可通过建立了一个Request对象来明确指明想要获取的url。调用urlopen函数对请求的url返回一个response对 象。这个response类似于一个file对象,所以用.read()函数可以操作这个response对象

url = 'http://m.sohu.com/?v=3&_once_=000025_v2tov3&_smuid\
  =ICvXXapq5EfTpQTVq6Tpz'
  req = urllib2.Request(url)
  resp = urllib2.urlopen(req)
  page = resp.read()

II.2 class urllib2.Request(url[, data][, headers][, originreqhost][, unverifiable])

II.2.1 Request类是一个抽象的URL请求。

5个参数的说明如下:

II.2.1.1 URL——是一个字符串,其中包含一个有效的URL。

II.2.1.2 data——是一个字符串,指定额外的数据发送到服务器,如果没有data需要发送可以为“None”。目前使用data的HTTP请求是唯一的。当请求 含有data参数时,HTTP的请求为POST,而不是GET。数据应该是缓存在一个标准的application/x-www-form- urlencoded格式中。urllib.urlencode()函数用映射或2元组,返回一个这种格式的字符串。通俗的说就是如果想向一个URL发送 数据(通常这些数据是代表一些CGI脚本或者其他的web应用)。例如在网上填的form(表单)时,浏览器会POST表单的内容,这些数据需要被以标准 的格式编码(encode),然后作为一个数据参数传送给Request对象。Encoding是在urlib模块中完成的,而不是在urlib2中完成 的。下面是个例子:

import urllib
import urllib2
url = 'http://www.someserver.com/cgi-bin/register.cgi'values = {'name' : 'Michael Foord',    'location' : 'Northampton',    'language' : 'Python' }
data = urllib.urlencode(values)   
req = urllib2.Request(url, data)  #send post
response = urllib2.urlopen(req)
page = response.read()

II.2.1.3 headers——是字典类型,头字典可以作为参数在request时直接传入,也可以把每个键和值作为参数调用add_header()方法来添加。

作 为辨别浏览器身份的User-Agent header是经常被用来恶搞和伪装的,因为一些HTTP服务只允许某些请求来自常见的浏览器而不是脚本,或是针对不同的浏览器返回不同的版本。

例 如,Mozilla Firefox浏览器被识别为“Mozilla/5.0 (X11; U; Linux i686) Gecko/20071127 Firefox/2.0.0.11”。默认情况下,urlib2把自己识别为Python-urllib/x.y(这里的xy是python发行版的主要 或次要的版本号,如在Python 2.6中,urllib2的默认用户代理字符串是“Python-urllib/2.6。

下面的例子和上面的区别就是在请求时加了一个headers,模 仿IE浏览器提交请求。

import urllib
import urllib2
url = 'http://www.someserver.com/cgi-bin/register.cgi'user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'values = {'name' : 'Michael Foord',    'location' : 'Northampton',    'language' : 'Python' }
headers = { 'User-Agent' : user_agent }
data = urllib.urlencode(values)
req = urllib2.Request(url, data, headers)
response = urllib2.urlopen(req)
the_page = response.read()

标准的headers组成是(Content-Length, Content-Type and Host),只有在Request对象调用urlopen()(上面的例子也属于这个情况)或者OpenerDirector.open()时加入。

两种 情况的例子如下: 使用headers参数构造Request对象,如上例在生成Request对象时已经初始化header,而下例是Request对象调用 add_header(key, val)方法附加header(Request对象的方法下面再介绍):

import urllib2
req = urllib2.Request('http://www.example.com/')
req.add_header('Referer', 'http://www.python.org/')  
 #http是无状态的协议,上一次客户端的请求与下一次客户端到服务器的请求无关系的,多数省略这一步
r = urllib2.urlopen(req)

OpenerDirector为每一个Request自动加上一个User-Agent header,所以第二种方法如下(urllib2.buildopener会返回一个OpenerDirector对象,关于urllib2.buildopener类下面再说):

import urllib2
opener = urllib2.build_opener()
opener.addheaders = [('User-agent', 'Mozilla/5.0')]
opener.open('http://www.example.com/')

II.3 urllib2.installopener(opener)和urllib2.buildopener([handler, ...]) 

installopener和buildopener这两个方法通常都是在一起用,也有时候buildopener单独使用来得到OpenerDirector对象。

installopener 实例化会得到OpenerDirector 对象用来赋予全局变量opener。如果想用这个opener来调用urlopen,那么就必须实例化得到OpenerDirector;这样就可以简单 的调用OpenerDirector.open()来代替urlopen()。

build_opener实例化也会得到 OpenerDirector对象,其中参数handlers可以被BaseHandler或他的子类实例化。子类中可以通过以下实例 化:ProxyHandler (如果检测代理设置用)扫描代理会用到,很重要这个, UnknownHandler, HTTPHandler, HTTPDefaultErrorHandler, HTTPRedirectHandler, FTPHandler, FileHandler, HTTPErrorProcessor。

import urllib2
req = urllib2.Request('http://www.python.org/')
opener=urllib2.build_opener()
urllib2.install_opener(opener)
f = opener.open(req)

如上使用 urllib2.install_opener()设置 urllib2 的全局 opener。这样后面的使用会很方便,但不能做更细粒度的控制,比如想在程序中使用两个不同的 Proxy 设置等。

比较好的做法是不使用 install_opener 去更改全局的设置,而只是直接调用 opener的open 方法代替全局的 urlopen 方法。

说到这Opener和Handler之间的操作听起来有点晕。整理下思路就清楚了。

当获取一个URL时,可以使用一 个opener(一个urllib2.OpenerDirector实例对象,可以由build_opener实例化生成)。

正常情况下程 序一直通过urlopen使用默认的opener(也就是说当你使用urlopen方法时,是在隐式的使用默认的opener 对象),但也可以创建自定义的openers(通过操作 器handlers创建的opener实例)。

所有的重活和麻烦 都交给这些handlers来做。

每一个handler知道如何以一种特定的协议(http,ftp等等)打开url,或 者如何处理打开url发生的HTTP重定向,或者包含的HTTP cookie。

创建openers时如果想要安装特别的han dlers来实现获取url(如获取一个处理cookie的opener,或者一个不处理重定向的opener)的话,先实例 一个OpenerDirector对象,然后多次调用.add_handler(some_handler_instance)来创建一个opene r。

或者,你可以用build_opener,这是一个很方便的创建opener对象的函数,它只有一个函数调用 。

build_opener默认会加入许多handlers,它提供了一个快速的方法添加更多东西和使默认的handler 失效。

install_opener如上所述也能用于创建一个opener对象,但是这个对象是(全局)默认的opener。

这意味着调用urlopen 将会用到你刚创建的opener。

也就是说上面的代码可以等同于下面这段。这段代码最终还是使用的默认opener。

一般情况下我们用 build_opener为的是生成自定义opener,没有必要调用install_opener,除非是为了方便。

import urllib2
req = urllib2.Request('http://www.python.org/')
opener=urllib2.build_opener()    # 创建opener对象
urllib2.install_opener(opener)   #定义全局默认opener
f = urllib2.urlopen(req)     #urlopen使用默认opener,但是install_opener
 #已经把opener设为全局默认了,这里便是使用上面的建立的opener

III. 异常处理//3water.com/article/63711.htm当我们调用urllib2.urlopen的时候不会总是这么顺利,就像浏览器打开url时有时也会报 错,所以就需要我们有应对异常的处理。说到异常,我们先来了解返回的response对象的 几个常用的方法:

geturl() — 返回检索的URL资源,这个是返回的真正url,通常是用来鉴定是否重定向的

info() — 返回页面的原信息就像一个字段的对象, 如headers,它以mimetools.Message实例为格式(可以参考HTTP Headers说明)。

getcode() — 返回响应的HTTP状态代码,运行下面代码可以得到code=200 当不能处理一个response时,urlopen抛出一个URLError(对于python APIs,内建异常如,ValueError, TypeError 等也会被抛出。)

HTTPError是HTTP URL在特别的情况下被抛出的URLError的一个子类。下面就详细说说URLError和HTTPError。 URLError——handlers当运行出现问题时(通常是因为没有网络连接也就是没有路由到指定的服务器,或在指定的服务器不存在)

HTTPError——HTTPError是URLError的子类。每个来自服务器HTTP的response都包含“status code”. 有时status code不能处理这个request. 默认的处理程序将处理这些异常的responses。例如,urllib2发现response的URL与你请求的URL不同时也就是发生了重定向时,会 自动处理。对于不能处理的请求, urlopen将抛出 - - - HTTPError异常. 典型的错误包含‘404' (没有找到页面), ‘403' (禁止请求),‘401' (需要验证)等。它包含2个重要的属性reason和code。

程序对于重定向时默认处理的

总结

如果只是单纯的下载或者显示下载进度,不对下载后的内容做处理等,比如下载图片,css,js文件等,可以用urlilb.urlretrieve()

如果是下载的请求需要填写表单,输入账号,密码等,建议用urllib2.urlopen(urllib2.Request())

在对字典数据编码时候,用到的是urllib.urlencode()

requests

I. Requests 使用的是 urllib3,继承了urllib2的所有特性。Requests支持HTTP连接保持和连接池,支持使用cookie保持会话,支持文件上传,支持自 动确定响应内容的编码,支持国际化的 URL 和 POST 数据自动编码。 II. 举例:

import requests
   ...

   resp = requests.get('http://www.mywebsite.com/user')
   userdata = {"firstname": "John", "lastname": "Doe", "password": "jdoe123"}
   resp = requests.post('http://www.mywebsite.com/user', params=userdata)
   resp = requests.put('http://www.mywebsite.com/user/put')
   resp = requests.delete('http://www.mywebsite.com/user/delete')
   resp.json()  # 假如返回的是json数据
   resp.text   #返回的不是text数据
   resp.headers['content-type'] #返回text/html;charset=utf-8
   f = open('request_index.html', 'w')
   f.write(page.encode('utf8'))     
   #test 发现requests抓下来的页面必须要编码\
   #写入,(抓下来的是unicode),urllib和urllib2抓下来可以直接写入,
   #因为这两者抓下来的page是str

III. 其他功能特性

国际化域名和 URLs

Keep-Alive & 连接池

持久的 Cookie 会话

类浏览器式的 SSL 加密认证

基本/摘要式的身份认证

优雅的键/值 Cookies

自动解压

Unicode 编码的响应体

多段文件上传

连接超时

支持 .netrc

适用于 Python 2.6—3.4线程安全

IV. requests不是python自带的库,需要另外安装 easy_install or pip install

V. requests缺陷:直接使用不能异步调用,速度慢(from others)。官方的urllib可以替代它。

VI. 个人不建议使用requests模块

更详细的相关介绍

urllib 官网

urllib2 官网

以上这篇django queryset 去重 .distinct()说明就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python与人工神经网络:使用神经网络识别手写图像介绍
Dec 19 Python
Python实现自定义函数的5种常见形式分析
Jun 16 Python
Python切片操作深入详解
Jul 27 Python
python中pip的安装与使用教程
Aug 10 Python
python 产生token及token验证的方法
Dec 26 Python
Python3+OpenCV2实现图像的几何变换(平移、镜像、缩放、旋转、仿射)
May 13 Python
24式加速你的Python(小结)
Jun 13 Python
pandas 数据结构之Series的使用方法
Jun 21 Python
python 判断三个数字中的最大值实例代码
Jul 24 Python
Django用户认证系统 Web请求中的认证解析
Aug 02 Python
keras打印loss对权重的导数方式
Jun 10 Python
Python图像阈值化处理及算法比对实例解析
Jun 19 Python
django正续或者倒序查库实例
May 19 #Python
Django model.py表单设置默认值允许为空的操作
May 19 #Python
django 模型中的计算字段实例
May 19 #Python
Django获取model中的字段名和字段的verbose_name方式
May 19 #Python
Python日志处理模块logging用法解析
May 19 #Python
基于PyQT实现区分左键双击和单击
May 19 #Python
Python更换pip源方法过程解析
May 19 #Python
You might like
CodeIgniter钩子用法实例详解
2016/01/20 PHP
PHP实现防止表单重复提交功能【基于token验证】
2018/05/24 PHP
Javascript学习笔记2 函数
2010/01/11 Javascript
jQuery EasyUI API 中文文档 - TimeSpinner时间微调器
2011/10/23 Javascript
jQuery插件-jRating评分插件源码分析及使用方法
2012/12/28 Javascript
javascript中字符串拼接详解
2014/09/26 Javascript
js树插件zTree获取所有选中节点数据的方法
2015/01/28 Javascript
微信小程序开发一键登录 获取session_key和openid实例
2016/11/23 Javascript
jquery点赞功能实现代码 点个赞吧!
2020/05/29 jQuery
Javascript实现一个简单的输入关键字添加标签效果实例
2017/06/01 Javascript
vue实现form表单与table表格的数据关联功能示例
2019/01/29 Javascript
JavaScript ES2019中的8个新特性详解
2019/02/20 Javascript
详解javascript函数写法大全
2019/03/25 Javascript
基于Vue的商品主图放大镜方案详解
2019/09/19 Javascript
[38:27]完美世界DOTA2联赛PWL S2 Forest vs FTD.C 第二场 11.26
2020/11/30 DOTA
Python Web框架Flask信号机制(signals)介绍
2015/01/01 Python
python 随机数使用方法,推导以及字符串,双色球小程序实例
2017/09/12 Python
手把手教你如何安装Pycharm(详细图文教程)
2018/11/28 Python
解决新版Pycharm中Matplotlib图像不在弹出独立的显示窗口问题
2019/01/15 Python
python return逻辑判断表达式实现解析
2019/12/02 Python
python操作cfg配置文件方式
2019/12/22 Python
Python rabbitMQ如何实现生产消费者模式
2020/08/24 Python
python通过函数名调用函数的几种场景
2020/09/23 Python
CSS3 @keyframes简单动画实现
2018/02/24 HTML / CSS
ALEX AND ANI:手镯,项链,耳环和更多
2017/04/20 全球购物
专升本自我鉴定
2013/10/10 职场文书
医院学雷锋活动策划方案
2014/02/15 职场文书
机房搬迁方案
2014/05/01 职场文书
培训科主任岗位职责
2014/08/08 职场文书
考研英语复习计划
2015/01/19 职场文书
2015年简历自我评价范文
2015/03/11 职场文书
你会写报告?产品体验报告到底该怎么写?
2019/08/14 职场文书
创业计划书之情侣餐厅
2019/09/29 职场文书
解决Pytorch中关于model.eval的问题
2021/05/22 Python
Win11怎么启动任务管理器?Win11启动任务管理器的几种方法
2021/11/23 数码科技
ORACLE中dbms_output.put_line输出问题的解决过程
2022/06/28 Oracle