HttpRequest 对象
下面除非特别说明,所有属性都认为是只读的。会话(session) 属性是个例外,需要注意。
HttpRequest.scheme
一个字符串,表示请求的方案 (通常是http 和 https)
HttpRequest.body
一个字节字符串,表示原始HTTP 请求的正文
HttpRequest.path
一个字符串,表示请求的页面的完整路径,不包含域名
/music/bands/the_beatles/
HttpRequest.path_info
某些Web 服务器配置下,主机名后的URL 部分被分成脚本前缀部分和路径信息部分。path_info 属性将始终包含路径信息部分,不论使用的Web 服务器是什么。使用它代替path 可以让代码在测试和开发环境中更容易地切换。例如,如果应用的WSGIScriptAlias 设置为"/minfo",那么当path 是"/minfo/music/bands/the_beatles/" 时path_info将是"/music/bands/the_beatles/"
HttpRequest.method
一个字符串,表示请求使用的HTTP方法,必须用大写:
if request.method == 'GET': do_something()
HttpRequest.encoding
一个字符串,表示提交的数据的编码方式(如果为None则表示使用DEFAULT_CHARSET), 这个属性是可写的,可以修改它来修改访问表单数据使用的编码,接下来对属性的访问使用新的encoding
HttpRequest.content_type
表示请求的MIME类型的字符串, 从CONTENT_TYPE 头解析
HttpRequest.content_params
包含在 CONTENT_TYPE 头中的键/值参数的字典。
HttpRequest.GET
一个类似字典对象,包含所有get参数
HttpRequest.POST
包含所有给定POST参数的字典对象,提供包含表单数据请求。
HttpRequest.COOKIES
包含所有COOKIE的标准python字典, 键和值都是字符串
HttpRequest.FILES
包含所有已上传文件的类似字典的对象,FILES 中的每个键来自 <input type="file"name="" />
的 name
FILES 中的每个值是 UploadedFile
注意,FILES 只有在请求的方法为POST 且提交的<form> 带有enctype="multipart/form-data" 的情况下才会包含数据。否则,FILES 将为一个空的类似于字典的对象
HttpRequest.META
一个标准的Python 字典,包含所有的HTTP 头部。具体的头部信息取决于客户端和服务器,下面是一些示例:
- CONTENT_LENGTH —— 请求的正文的长度(是一个字符串)。
- CONTENT_TYPE —— 请求的正文的MIME 类型。
- HTTP_ACCEPT —— 响应可接收的Content-Type。
- HTTP_ACCEPT_ENCODING —— 响应可接收的编码。
- HTTP_ACCEPT_LANGUAGE —— 响应可接收的语言。
- HTTP_HOST —— 客服端发送的HTTP Host 头部。
- HTTP_REFERER —— Referring 页面。
- HTTP_USER_AGENT —— 客户端的user-agent 字符串。
- QUERY_STRING —— 单个字符串形式的查询字符串(未解析过的形式)。
- REMOTE_ADDR —— 客户端的IP 地址。
- REMOTE_HOST —— 客户端的主机名。
- REMOTE_USER —— 服务器认证后的用户。
- REQUEST_METHOD —— 一个字符串,例如"GET" 或"POST"。
- SERVER_NAME —— 服务器的主机名。
- SERVER_PORT —— 服务器的端口(是一个字符串)。
从上面可以看到,除CONTENT_LENGTH 和CONTENT_TYPE 之外,请求中的任何HTTP 头部转换为META 的键时,都会将所有字母大写并将连接符替换为下划线最后加上HTTP_ 前缀。所以,一个叫做X-Bender 的头部将转换成META 中的HTTP_X_BENDER 键
HttpRequest.user
一个AUTH_USER_MODEL 类型的对象,表示当前登录的用户。如果用户当前没有登录,user 将设置为django.contrib.auth.models.AnonymousUser 的一个实例。你可以通过is_authenticated() 区分它们,像这样:
if request.user.is_authenticated(): # Do something for logged-in users. else: # Do something for anonymous users.
user 只有当Django 启用AuthenticationMiddleware 中间件时才可用
HttpRequest.session
一个既可读又可写的类似于字典的对象,表示当前的会话。只有当Django 启用会话的支持时才可用
HttpRequest.urlconf
不是由Django 自身定义的,但是如果其它代码(例如,自定义的中间件类)设置了它,Django 就会读取它。如果存在,它将用来作为当前的请求的Root URLconf,并覆盖ROOT_URLCONF 设置。细节参见Django 如何处理请求。
HttpRequest.resolver_match
一个ResolverMatch 的实例,表示解析后的URL。这个属性只有在URL 解析方法之后才设置,这意味着它在所有的视图中可以访问,但是在在URL 解析发生之前执行的中间件方法中不可以访问(比如process_request,但你可以使用process_view 代替)。
方法
HttpRequest.get_host()
根据从HTTP_X_FORWARDED_HOST(如果打开USE_X_FORWARDED_HOST)和HTTP_HOST 头部信息返回请求的原始主机。如果这两个头部没有提供相应的值,则使用SERVER_NAME 和SERVER_PORT
例如:"127.0.0.1:8000"
当主机位于多个代理的后面,get_host() 方法将会失败。有一个解决办法是使用中间件重写代理的头部
class MultipleProxyMiddleware(object): FORWARDED_FOR_FIELDS = [ 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED_HOST', 'HTTP_X_FORWARDED_SERVER', ] def process_request(self, request): """ Rewrites the proxy headers so that only the most recent proxy is used. """ for field in self.FORWARDED_FOR_FIELDS: if field in request.META: if ',' in request.META[field]: parts = request.META[field].split(',') request.META[field] = parts[-1].strip()
这个中间件应该放置在所有依赖于get_host() 的中间件之前 。 例如,CommonMiddleware 和CsrfViewMiddleware。
HttpRequest.get_full_path()
返回path,如果可以将加上查询字符串。
例如:"/music/bands/the_beatles/?print=true"
HttpRequest.build_absolute_uri(location)
返回location 的绝对URI。如果location 没有提供,则设置为request.get_full_path()。
如果URI 已经是一个绝对的URI,将不会修改。否则,使用请求中的服务器相关的变量构建绝对URI。
例如:"http://example.com/music/bands/the_beatles/?print=true"
HttpRequest.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None)
返回签名过的Cookie 对应的值,如果签名不再合法则返回django.core.signing.BadSignature。如果提供default 参数,将不会引发异常并返回default 的值。
可选参数salt 可以用来对安全密钥强力攻击提供额外的保护。max_age 参数用于检查Cookie 对应的时间戳以确保Cookie 的时间不会超过max_age 秒。
示例:
>>> request.get_signed_cookie('name') 'Tony' >>> request.get_signed_cookie('name', salt='name-salt') 'Tony' # assuming cookie was set using the same salt >>> request.get_signed_cookie('non-existing-cookie') ... KeyError: 'non-existing-cookie' >>> request.get_signed_cookie('non-existing-cookie', False) False >>> request.get_signed_cookie('cookie-that-was-tampered-with') ... BadSignature: ... >>> request.get_signed_cookie('name', max_age=60) ... SignatureExpired: Signature age 1677.3839159 > 60 seconds >>> request.get_signed_cookie('name', False, max_age=60) False
HttpRequest.is_secure()
如果请求时是安全的,则返回True;即请求是通过HTTPS 发起的
HttpRequest.is_ajax()
如果请求是通过XMLHttpRequest 发起的,则返回True,方法是检查HTTP_X_REQUESTED_WITH 头部是否是字符串'XMLHttpRequest'。大部分现代的JavaScript 库都会发送这个头部。如果你编写自己的XMLHttpRequest 调用(在浏览器端),你必须手工设置这个值来让is_ajax() 可以工作。
如果一个响应需要根据请求是否是通过AJAX 发起的,并且你正在使用某种形式的缓存例如Django 的cache middleware, 你应该使用vary_on_headers('HTTP_X_REQUESTED_WITH') 装饰你的视图以让响应能够正确地缓存。
HttpRequest.read(size=None)
HttpRequest.readline()
HttpRequest.readlines()
HttpRequest.xreadlines()
HttpRequest.__iter__()
这几个方法实现类文件的接口用于读取HttpRequest· 实例。这使得可以用流的方式读取进来的请求。一个常见的用例是使用迭代解析器处理大型XML有效载荷,而不在内存中构造一个完整的XML树。
根据这个标准的接口,一个HttpRequest 实例可以直接传递给XML 解析器,例如ElementTree:
import xml.etree.ElementTree as ET for element in ET.iterparse(request): process(element)
QueryDict 对象
在HttpRequest对象中,GET和POST是 django.http.QueryDict 的实例,他是一个类似字典的类,用来处理同一个键带有多个值。request.POST 和request.GET 的QueryDict 在一个正常的请求/响应循环中是不可变的。若要获得可变的版本,需要使用.copy()
方法
QueryDict 实现了字典所有方法,因为是字典的子类
不同点:
QueryDict.__init__(query_string=None, mutable=False, encoding=None)
基于 query_string 实例化 QueryDict 一个对象
GET = QueryDict('a=1&a=2&c=3')
<QueryDict: {'c': ['3'], 'a': ['1', '2']}>
如果 query_string 没有被传入, QueryDict 的结果是空的 (将没有键和值)
QueryDict 对象大都是不可修改的,如 request.POST 和 request.GET , 如果需要修改对象,通过设置
mutable = True,
QueryDict.__getitem__(key)
返回给出的key 值, 如果key具有多个值, __getitem__() 返回最新的值,如果key不存在,则引发KeyError
GET.__getitem__('a')
'2'
QueryDict.__setitem__(key, value)
设置给出的key 的值为[value](一个Python 列表,它具有唯一一个元素value)。注意,这和其它具有副作用的字典函数一样,只能在可变的QueryDict 上调用(如通过copy() 创建的字典)
POST = QueryDict('x=11&y=22', mutable=True)
POST.__setitem__('d', [5])
POST.__setitem__('y', 33)
POST
<QueryDict: {'x': ['11'], 'd': [[5]], 'y': [33]}>
POST.__setitem__('y', [22, 33])
POST
<QueryDict: {'x': ['11'], 'd': [[5]], 'y': [[22, 33]]}>
QueryDict 实例如果不是可变的,使用 __setitem__ 方法会引发错误 This QueryDict instance is immutable
QueryDict.__contains__(key)
如果给出的key 已经设置,则返回True。它让你可以做if "foo" in request.GET 这样的操作
GET.__contains__('a')
True
QueryDict.get(key, default)
使用与上面__getitem__() 相同的逻辑,但是当key 不存在时返回一个默认值
QueryDict.setdefault(key, default)
类似标准字典的setdefault() 方法,只是它在内部使用的是__setitem__(), 这里也要可变的对象
QueryDict.update(other_dict)
接收一个QueryDict 或标准字典。类似标准字典的update() 方法,但是它附加到当前字典项的后面,而不是替换掉它们
POST.update(GET)
POST
<QueryDict: {'c': ['3'], 'x': ['11'], 'a': ['1', '2'], 'd': [[5]], 'y': [[22, 33]]}>
QueryDict.items()
类似标准字典的items() 方法,返回一个生成器,返回最新值
q.items().__next__()
('a', '3')
QueryDict.values()
q = QueryDict('a=1&a=2&a=3')
q.values()
<generator object MultiValueDict._itervalues at 0x7fa5064df468>
q.values().__next__()
'3'
QueryDict.copy()
返回对象的副本,使用Python 标准库中的copy.deepcopy()。此副本是可变的即使原始对象是不可变的.
QueryDict.getlist(key, default)
以Python 列表形式返回所请求的键的数据。如果键不存在并且没有提供默认值,则返回空列表。它保证返回的是某种类型的列表,除非默认值不是列表
q = QueryDict('a=1&a=2&a=3')
q.getlist('a')
['1', '2', '3']
QueryDict.setlist(key, list_)
设置给定的键为list_(与__setitem__() 不同)
p = QueryDict('a=1&a=2&b=3')
p = QueryDict('a=1&a=2&b=3', mutable=True)
p.setlist('b', [5, 6])
p
<QueryDict: {'a': ['1', '2'], 'b': [5, 6]}>
QueryDict.appendlist(key, item)
将项追加到内部与键相关联的列表中。
QueryDict.setlistdefault(key, default_list)
类似setdefault,除了它接受一个列表而不是单个值
QueryDict.lists()¶
类似items,只是它将字典中的每个成员作为列表。例如:
p.lists()
<dict_itemiterator object at 0x7fc07a25a138>
for i in p.lists():
print(i)
('a', ['1', '2'])
('b', [5, 6])
QueryDict.pop(key)
返回给定键的值的列表,并从字典中移除它们。如果键不存在,将引发KeyError
p.pop('a')
['1', '2']
p
<QueryDict: {'b': [5, 6]}>
QueryDict.popitem()
删除字典任意一个成员(因为没有顺序的概念),并返回二值元组,包含键和键的所有值的列表。在一个空的字典上调用时将引发KeyError。例如 ︰
>>> q = QueryDict('a=1&a=2&a=3', mutable=True) >>> q.popitem() ('a', ['1', '2', '3'])
QueryDict.dict()
返回QueryDict 的dict 表示形式。对于QueryDict 中的每个(key, list)对 ,dict 将有(key, item) 对,其中item 是列表中的一个元素,使用与QueryDict.__getitem__()相同的逻辑:
>>> q = QueryDict('a=1&a=3&a=5') >>> q.dict() {'a': '5'}
QueryDict.urlencode([safe])
在查询字符串格式返回数据的字符串形式。示例︰
>>> q = QueryDict('a=2&b=3&b=5') >>> q.urlencode() 'a=2&b=3&b=5'
可选地,urlencode 可以传递不需要编码的字符。例如︰
>>> q = QueryDict(mutable=True) >>> q['next'] = '/a&b/' >>> q.urlencode(safe='/') 'next=/a%26b/'
HttpResponse 对象
用法
传递字符串
典型的应用是传递一个字符串作为页面的内容到HttpResponse 构造函数:
def index(request): return HttpResponse('hello')
传递迭代器
传递一个迭代器,HttpResponse 将立即处理这个迭代器,把它的内容存成字符串,并丢弃它
配置 header fields
把它当作一个类似字典的结构,从你的response中设置和移除一个header field。
>>> response = HttpResponse() >>> response['Age'] = 120 >>> del response['Age']
注意!与字典不同的是,如果要删除的header field不存在,del不会抛出KeyError异常。
对于设置Cache-Control和Vary头字段,建议使用django.utils.cache中的patch_cache_control()和patch_vary_headers()方法,因为这些字段可以有多个逗号分隔的值。“补丁”方法确保其他值,例如,通过中间件添加的,不会删除。
HTTP header fields 不能包含换行。当我们尝试让header field包含一个换行符(CR 或者 LF),那么将会抛出一个BadHeaderError异常
告诉浏览器以文件附件的形式处理服务器的响应
让浏览器以文件附件的形式处理响应, 需要声明 content_type 类型 和设置 Content-Disposition 头信息. 例如,下面是 如何给浏览器返回一个微软电子表格
>>> response = HttpResponse(my_data, content_type='application/vnd.ms-excel') >>> response['Content-Disposition'] = 'attachment; filename="foo.xls"
属性
HttpResponse.content
一个用来代替content的字节字符串,如果必要,则从一个Unicode对象编码而来
HttpResponse.charset
一个字符串,用来表示response将会被编码的字符集。如果没有在HttpResponse实例化的时候给定这个字符集,那么将会从content_type 中解析出来。并且当这种解析成功的时候,DEFAULT_CHARSET选项将会被使用
HttpResponse.status_code
响应(response)的HTTP 响应状态码
HttpResponse.reason_phrase
响应的HTTP原因短语。
HttpResponse.streaming
这个选项总是False。由于这个属性的存在,使得中间件(middleware)能够区别对待流式response和常规response。
HttpResponse.closed
如果响应已关闭为True
方法
HttpResponse.__init__(content='', content_type=None, status=200, reason=None, charset=None)
content 应该是一个迭代器或者字符串。如果它是一个迭代器,那么他应该返回的是一串字符串,并且这些字符串连接起来形成response的内容(content)。如果不是迭代器或者字符串,那么在其被接收的时候将转换成字符串
content_type是可选地通过字符集编码完成的MIME类型,并且用于填充HTTP Content-Type头部。如果没有设定, 会从DEFAULT_CONTENT_TYPE 和 DEFAULT_CHARSET 设定中提取, 作为默认值: “text/html; charset = utf-8“
status 是 HTTP 响应状态码 。.
reason 是HTTP响应短语 如果没有指定, 则使用默认响应短语.
charset 在response中被编码的字符集。如果没有给定,将会从content_type中提取, 如果提取不成功, 那么 DEFAULT_CHARSET 的设定将被使用
HttpResponse.__setitem__(header, value)
由给定的首部名称和值设定相应的报文首部。 header 和 value 都应该是字符串类型。
HttpResponse.__delitem__(header)
根据给定的首部名称来删除报文中的首部。如果对应的首部不存在将沉默地(不引发异常)失败。不区分大小写。
HttpResponse.__getitem__(header)
根据首部名称返回其值。不区分大小写。
HttpResponse.has_header(header)
通过检查首部中是否有给定的首部名称(不区分大小写),来返回True 或 False 。
HttpResponse.setdefault(header, value)
设置一个首部,除非该首部 header 已经存在了
HttpResponse.set_cookie(key, value='', max_age=None, expires=None, path='/', domain=None, secure=None, httponly=False)
设置一个Cookie。参数与Python 标准库中的Morsel Cookie 对象相同。
-
max_age 以秒为单位,如果Cookie 只能和session存在时间一样长,为NONE。如果没有指定expires,则会通过计算得到。
-
expires 应该是一个 UTC "Wdy, DD-Mon-YY HH:MM:SS GMT"格式的字符串,或者一个datetime.datetime 对象。如果expires 是一个datetime 对象,则max_age 会通过计算得到。
-
如果你想设置一个跨域的Cookie,请使用domain 参数。例如,domain=".lawrence.com" 将设置一个www.lawrence.com、blogs.lawrence.com 和calendars.lawrence.com 都可读的Cookie。否则,Cookie 将只能被设置它的域读取。
-
如果你想阻止客服端的JavaScript 访问Cookie,可以设置httponly=True。
HTTPOnly 是包含在HTTP 响应头部Set-Cookie 中的一个标记。它不是RFC 2109 中Cookie 的标准,也并没有被所有的浏览器支持。但是,如果使用,它是一种降低客户端脚本访问受保护的Cookie 数据风险的有用的方法。
警告
如果视图存储大于4096 个字节的Cookie,Django 不会引发异常,但是浏览器将不能正确设置Cookie
HttpResponse.set_signed_cookie(key, value, salt='', max_age=None, expires=None, path='/', domain=None, secure=None, httponly=True)
与set_cookie() 类似,但是在设置之前将用密钥签名。通常与HttpRequest.get_signed_cookie() 一起使用。你可以使用可选的salt 参考来增加密钥强度,但需要记住将它传递给对应的HttpRequest.get_signed_cookie() 调用。
HttpResponse.delete_cookie(key, path='/', domain=None)
删除指定的key 的Cookie。如果key 不存在则什么也不发生。由于Cookie 的工作方式,path 和domain 应该与set_cookie() 中使用的值相同 —— 否则Cookie 不会删掉。
HttpResponse.write(content)
此方法使HttpResponse实例是一个类似文件的对象。
HttpResponse.flush()
此方法使HttpResponse实例是一个类似文件的对象。
HttpResponse.tell()
此方法使HttpResponse实例是一个类似文件的对象。
HttpResponse.getvalue()
返回HttpResponse.content的值。此方法使HttpResponse实例是一个类似流的对象。
HttpResponse.writable()
始终为True。此方法使HttpResponse实例是一个类似流的对象。
HttpResponse.writelines(lines)
将一个包含行的列表写入响应。不添加行分隔符。此方法使HttpResponse实例是一个类似流的对象
HttpResponse的子类
Django包含了一系列的HttpResponse衍生类(子类),用来处理不同类型的HTTP 响应(response)。与 HttpResponse相同, 这些衍生类(子类)存在于django.http之中。
class HttpResponseRedirect
构造函数的第一个参数是必要的 — 用来重定向的地址。这些能够是完全特定的URL地址(比如,'http://www.yahoo.com/search/'),或者是一个不包含域名的绝对路径地址(例如, '/search/')。关于构造函数的其他参数,可以参见 HttpResponse。注意!这个响应会返回一个302的HTTP状态码。
url
这个只读属性,代表响应将会重定向的URL地址(相当于Location response hader)。
class HttpResponsePermanentRedirect
与HttpResponseRedirect一样,但是它会返回一个永久的重定向(HTTP状态码301)而不是一个“found”重定向(状态码302)。
class HttpResponseNotModified
构造函数不会有任何的参数,并且不应该向这个响应(response)中加入内容(content)。使用此选项可指定自用户上次请求(状态代码304)以来尚未修改页面。
class HttpResponseBadRequest
与HttpResponse的行为类似,但是使用了一个400的状态码。
class HttpResponseNotFound
与HttpResponse的行为类似,但是使用的404状态码。
class HttpResponseForbidden
与HttpResponse类似,但使用403状态代码。
class HttpResponseNotAllowed
与HttpResponse类似,但使用405状态码。构造函数的第一个参数是必须的:一个允许使用的方法构成的列表(例如,['GET','POST'])。
class HttpResponseGone
与HttpResponse类似,但使用410状态码。
class HttpResponseServerError
与HttpResponse类似,但使用500状态代码。
注意
如果HttpResponse的自定义子类实现了render方法,Django会将其视为模拟SimpleTemplateResponse,且render方法必须自己返回一个有效的响应对象。
JsonResponse 对象
class JsonResponse
JsonResponse.__init__(data, encoder=DjangoJSONEncoder, safe=True, **kwargs)
HttpResponse 的一个子类
它的默认Content-Type 头部设置为application/json。
它的第一个参数data,应该为一个dict 实例。如果safe 参数设置为False,它可以是任何可JSON 序列化的对象。
encoder,默认为django.core.serializers.json.DjangoJSONEncoder,用于序列化data。关于这个序列化的更多信息参见JSON 序列化。
布尔参数safe 默认为True。如果设置为False,可以传递任何对象进行序列化(否则,只允许dict 实例)。如果safe 为True,而第一个参数传递的不是dict 对象,将抛出一个TypeError
from django.http import JsonResponse
response = JsonResponse({'foo': 'bar'})
response.content
b'{"foo": "bar"}'
序列化非字典对象,必须设置safe为False,否则报错TypeError
response = JsonResponse([1,2,3], safe=False)
response.content
b'[1, 2, 3]'
修改默认的JSON 编码器
如果你需要使用不同的JSON 编码器类,你可以传递encoder 参数给构造函数:
>>> response = JsonResponse(data, encoder=MyJSONEncoder)
StreamingHttpResponse对象
class StreamingHttpResponse
StreamingHttpResponse类被用来从Django流式化一个响应(response)到浏览器。如果生成响应太长或者是有使用太多的内存,你可能会想要这样做。例如,它对于生成大型CSV文件非常有用。
基于性能的考虑
Django是为了那些短期的请求(request)设计的。流式响应将会为整个响应期协同工作进程。这可能导致性能变差。
总的来说,你需要将代价高的任务移除请求—响应的循环,而不是求助于流式响应。
StreamingHttpResponse 不是 HttpResponse的衍生类(子类),因为它实现了完全不同的应用程序接口(API)。尽管如此,除了以下的几个明显不同的地方,其他几乎完全相同:
- 应该提供一个迭代器给它,这个迭代器生成字符串来构成内容(content)
- 你不能直接访问它的内容(content),除非迭代它自己的响应对象。这只在响应被返回到客户端的时候发生。
- 它没有 content 属性。取而代之的是,它有一个 streaming_content 属性。
- 你不能使用类似文件对象的tell()或者 write() 方法。那么做会抛出一个异常。
StreamingHttpResponse应仅在绝对需要在将数据传输到客户端之前不重复整个内容的情况下使用。由于内容无法访问,许多中间件无法正常工作。例如,无法为流式响应生成ETag和Content-Length头。
属性¶
StreamingHttpResponse.streaming_content
一个表示内容(content)的字符串的迭代器
StreamingHttpResponse.status_code
响应的HTTP状态码。
StreamingHttpResponse.reason_phrase
响应的HTTP原因短语。
StreamingHttpResponse.streaming
这个选项总是 True.
FileResponse 对象
class FileResponse
FileResponse是StreamingHttpResponse的衍生类(子类),为二进制文件做了优化。如果 wsgi server 来提供,则使用了 wsgi.file_wrapper,否则将会流式化一个文件为一些小块。
FileResponse 需要通过二进制模式打开文件,如下:
>>> from django.http import FileResponse >>> response = FileResponse(open('myfile.png', 'rb'))