Django(三):HttpRequest和HttpResponse
当一个请求连接进来时,django会创建一个HttpRequest对象来封装和保存所有请求相关的信息,并且会根据请求路由载入匹配的视图函数。每个请求的视图函数都会返回一个HttpResponse。
HttpRequest和HttpResponse可以从django.http中导入。
1、HttpRequest类
函数 | 功能描述 |
HttpRequest .
scheme |
请求协议(http或者https) |
HttpRequest. body |
以字节的方式返回请求体内容;可以通过HttpRequest.POST获取处理后的key和value,也可以通过HttpRequest.read()格式化 |
HttpRequest. path |
返回请求的完整路径,不包括协议和域名 |
HttpRequest. GET |
GET请求参数,返回一个queryDict对象 |
HttpRequest. POST |
获取表单提交的数据,如果是通过POST请求提交的其它非表单数据,可以使用HttpRequest.Body获取;使用时可以通过if request.method == "PSOT"来进行预判断 |
HttpRequest .method |
返回请求方式 |
|
返回一个字典,包含所有django运行的环境信息 |
HttpRequest. content_type |
文件格式 |
HttpRequest. content_params |
参数 |
HttpRequest. COOKIES |
返回一个字典,包含浏览器存储的所有cookie |
HttpRequest. FILES |
返回一个MultiValueDict,包含上传的文件 |
HttpRequest. META |
返回一个包含所有请求相关信息的字典(包含Headers),同environ |
HttpRequest. resolver_match |
返回请求处理的url及相关参数 |
HttpRequest. session |
中间件,设置session,一个可读可写的字典对象 |
HttpRequest. get_host () |
获取请求的主机和端口 |
HttpRequest. get_port () |
获取端口 |
HttpRequest. get_full_path () |
返回完整路径,同path |
HttpRequest. get_signed_cookie (key, default=RAISE_ERROR, salt='', max_age=None) |
获取以一个cookie |
HttpRequest. is_ajax () |
判断是否为ajax请求 |
HttpRequest. is_secure () |
判断是否为https请求 |
示例:
- class HttpRequest:
- """A basic HTTP request."""
- # The encoding used in GET/POST dicts. None means use default setting.
- _encoding = None
- _upload_handlers = []
- def __init__(self):
- # WARNING: The `WSGIRequest` subclass doesn't call `super`.
- # Any variable assignment made here should also happen in
- # `WSGIRequest.__init__()`.
- self.GET = QueryDict(mutable=True)
- self.POST = QueryDict(mutable=True)
- self.COOKIES = {}
- self.META = {}
- self.FILES = MultiValueDict()
- self.path = ''
- self.path_info = ''
- self.method = None
- self.resolver_match = None
- self._post_parse_error = False
- self.content_type = None
- self.content_params = None
- def __repr__(self):
- if self.method is None or not self.get_full_path():
- return '<%s>' % self.__class__.__name__
- return '<%s: %s %r>' % (self.__class__.__name__, self.method, self.get_full_path())
- def _get_raw_host(self):
- """
- Return the HTTP host using the environment or request headers. Skip
- allowed hosts protection, so may return an insecure host.
- """
- # We try three options, in order of decreasing preference.
- if settings.USE_X_FORWARDED_HOST and (
- 'HTTP_X_FORWARDED_HOST' in self.META):
- host = self.META['HTTP_X_FORWARDED_HOST']
- elif 'HTTP_HOST' in self.META:
- host = self.META['HTTP_HOST']
- else:
- # Reconstruct the host using the algorithm from PEP 333.
- host = self.META['SERVER_NAME']
- server_port = self.get_port()
- if server_port != ('' if self.is_secure() else ''):
- host = '%s:%s' % (host, server_port)
- return host
- def get_host(self):
- """Return the HTTP host using the environment or request headers."""
- host = self._get_raw_host()
- # Allow variants of localhost if ALLOWED_HOSTS is empty and DEBUG=True.
- allowed_hosts = settings.ALLOWED_HOSTS
- if settings.DEBUG and not allowed_hosts:
- allowed_hosts = ['localhost', '127.0.0.1', '[::1]']
- domain, port = split_domain_port(host)
- if domain and validate_host(domain, allowed_hosts):
- return host
- else:
- msg = "Invalid HTTP_HOST header: %r." % host
- if domain:
- msg += " You may need to add %r to ALLOWED_HOSTS." % domain
- else:
- msg += " The domain name provided is not valid according to RFC 1034/1035."
- raise DisallowedHost(msg)
- def get_port(self):
- """Return the port number for the request as a string."""
- if settings.USE_X_FORWARDED_PORT and 'HTTP_X_FORWARDED_PORT' in self.META:
- port = self.META['HTTP_X_FORWARDED_PORT']
- else:
- port = self.META['SERVER_PORT']
- return str(port)
- def get_full_path(self, force_append_slash=False):
- # RFC 3986 requires query string arguments to be in the ASCII range.
- # Rather than crash if this doesn't happen, we encode defensively.
- return '%s%s%s' % (
- escape_uri_path(self.path),
- '/' if force_append_slash and not self.path.endswith('/') else '',
- ('?' + iri_to_uri(self.META.get('QUERY_STRING', ''))) if self.META.get('QUERY_STRING', '') else ''
- )
- def get_signed_cookie(self, key, default=RAISE_ERROR, salt='', max_age=None):
- """
- Attempt to return a signed cookie. If the signature fails or the
- cookie has expired, raise an exception, unless the `default` argument
- is provided, in which case return that value.
- """
- try:
- cookie_value = self.COOKIES[key]
- except KeyError:
- if default is not RAISE_ERROR:
- return default
- else:
- raise
- try:
- value = signing.get_cookie_signer(salt=key + salt).unsign(
- cookie_value, max_age=max_age)
- except signing.BadSignature:
- if default is not RAISE_ERROR:
- return default
- else:
- raise
- return value
- def get_raw_uri(self):
- """
- Return an absolute URI from variables available in this request. Skip
- allowed hosts protection, so may return insecure URI.
- """
- return '{scheme}://{host}{path}'.format(
- scheme=self.scheme,
- host=self._get_raw_host(),
- path=self.get_full_path(),
- )
- def build_absolute_uri(self, location=None):
- """
- Build an absolute URI from the location and the variables available in
- this request. If no ``location`` is specified, bulid the absolute URI
- using request.get_full_path(). If the location is absolute, convert it
- to an RFC 3987 compliant URI and return it. If location is relative or
- is scheme-relative (i.e., ``//example.com/``), urljoin() it to a base
- URL constructed from the request variables.
- """
- if location is None:
- # Make it an absolute url (but schemeless and domainless) for the
- # edge case that the path starts with '//'.
- location = '//%s' % self.get_full_path()
- bits = urlsplit(location)
- if not (bits.scheme and bits.netloc):
- current_uri = '{scheme}://{host}{path}'.format(scheme=self.scheme,
- host=self.get_host(),
- path=self.path)
- # Join the constructed URL with the provided location, which will
- # allow the provided ``location`` to apply query strings to the
- # base path as well as override the host, if it begins with //
- location = urljoin(current_uri, location)
- return iri_to_uri(location)
- def _get_scheme(self):
- """
- Hook for subclasses like WSGIRequest to implement. Return 'http' by
- default.
- """
- return 'http'
- @property
- def scheme(self):
- if settings.SECURE_PROXY_SSL_HEADER:
- try:
- header, value = settings.SECURE_PROXY_SSL_HEADER
- except ValueError:
- raise ImproperlyConfigured(
- 'The SECURE_PROXY_SSL_HEADER setting must be a tuple containing two values.'
- )
- if self.META.get(header) == value:
- return 'https'
- return self._get_scheme()
- def is_secure(self):
- return self.scheme == 'https'
- def is_ajax(self):
- return self.META.get('HTTP_X_REQUESTED_WITH') == 'XMLHttpRequest'
- @property
- def encoding(self):
- return self._encoding
- @encoding.setter
- def encoding(self, val):
- """
- Set the encoding used for GET/POST accesses. If the GET or POST
- dictionary has already been created, remove and recreate it on the
- next access (so that it is decoded correctly).
- """
- self._encoding = val
- if hasattr(self, 'GET'):
- del self.GET
- if hasattr(self, '_post'):
- del self._post
- def _initialize_handlers(self):
- self._upload_handlers = [uploadhandler.load_handler(handler, self)
- for handler in settings.FILE_UPLOAD_HANDLERS]
- @property
- def upload_handlers(self):
- if not self._upload_handlers:
- # If there are no upload handlers defined, initialize them from settings.
- self._initialize_handlers()
- return self._upload_handlers
- @upload_handlers.setter
- def upload_handlers(self, upload_handlers):
- if hasattr(self, '_files'):
- raise AttributeError("You cannot set the upload handlers after the upload has been processed.")
- self._upload_handlers = upload_handlers
- def parse_file_upload(self, META, post_data):
- """Return a tuple of (POST QueryDict, FILES MultiValueDict)."""
- self.upload_handlers = ImmutableList(
- self.upload_handlers,
- warning="You cannot alter upload handlers after the upload has been processed."
- )
- parser = MultiPartParser(META, post_data, self.upload_handlers, self.encoding)
- return parser.parse()
- @property
- def body(self):
- if not hasattr(self, '_body'):
- if self._read_started:
- raise RawPostDataException("You cannot access body after reading from request's data stream")
- # Limit the maximum request data size that will be handled in-memory.
- if (settings.DATA_UPLOAD_MAX_MEMORY_SIZE is not None and
- int(self.META.get('CONTENT_LENGTH') or 0) > settings.DATA_UPLOAD_MAX_MEMORY_SIZE):
- raise RequestDataTooBig('Request body exceeded settings.DATA_UPLOAD_MAX_MEMORY_SIZE.')
- try:
- self._body = self.read()
- except IOError as e:
- raise UnreadablePostError(*e.args) from e
- self._stream = BytesIO(self._body)
- return self._body
- def _mark_post_parse_error(self):
- self._post = QueryDict()
- self._files = MultiValueDict()
- self._post_parse_error = True
- def _load_post_and_files(self):
- """Populate self._post and self._files if the content-type is a form type"""
- if self.method != 'POST':
- self._post, self._files = QueryDict(encoding=self._encoding), MultiValueDict()
- return
- if self._read_started and not hasattr(self, '_body'):
- self._mark_post_parse_error()
- return
- if self.content_type == 'multipart/form-data':
- if hasattr(self, '_body'):
- # Use already read data
- data = BytesIO(self._body)
- else:
- data = self
- try:
- self._post, self._files = self.parse_file_upload(self.META, data)
- except MultiPartParserError:
- # An error occurred while parsing POST data. Since when
- # formatting the error the request handler might access
- # self.POST, set self._post and self._file to prevent
- # attempts to parse POST data again.
- # Mark that an error occurred. This allows self.__repr__ to
- # be explicit about it instead of simply representing an
- # empty POST
- self._mark_post_parse_error()
- raise
- elif self.content_type == 'application/x-www-form-urlencoded':
- self._post, self._files = QueryDict(self.body, encoding=self._encoding), MultiValueDict()
- else:
- self._post, self._files = QueryDict(encoding=self._encoding), MultiValueDict()
- def close(self):
- if hasattr(self, '_files'):
- for f in chain.from_iterable(l[1] for l in self._files.lists()):
- f.close()
- # File-like and iterator interface.
- #
- # Expects self._stream to be set to an appropriate source of bytes by
- # a corresponding request subclass (e.g. WSGIRequest).
- # Also when request data has already been read by request.POST or
- # request.body, self._stream points to a BytesIO instance
- # containing that data.
- def read(self, *args, **kwargs):
- self._read_started = True
- try:
- return self._stream.read(*args, **kwargs)
- except IOError as e:
- raise UnreadablePostError(*e.args) from e
- def readline(self, *args, **kwargs):
- self._read_started = True
- try:
- return self._stream.readline(*args, **kwargs)
- except IOError as e:
- raise UnreadablePostError(*e.args) from e
- def __iter__(self):
- while True:
- buf = self.readline()
- if not buf:
- break
- yield buf
- def xreadlines(self):
- warnings.warn(
- 'HttpRequest.xreadlines() is deprecated in favor of iterating the '
- 'request.', RemovedInDjango30Warning, stacklevel=2,
- )
- yield from self
- def readlines(self):
- return list(self)
HttpRequest源码
- from django.http import HttpResponse
- from django.views.decorators.csrf import csrf_exempt
- # views.py
- @csrf_exempt
- def page(request):
- # print(request.scheme)
- # print(request.GET)
- # print(request.POST)
- # print(request.method)
- # # print(request.encoding)
- # print(request.environ)
- # print(request.content_type)
- # print(request.content_params)
- # request.COOKIES["host"] = "whatever"
- # print(request.COOKIES)
- # print(request.FILES)
- # print(request.FILES.get("dog"))
- # print(request.META)
- # print(request.resolver_match)
- # request.session["username"] = "Jan"
- # print(request.session["username"])
- # print(request.get_signed_cookie("host"))
- # print(request.is_secure())
- # print(request.is_ajax())
- # print(request.POST.get("age", None))
- # print(request.get_port())
- # print(request.get_full_path())
- # print(request.path)
- # print(request.path_info)
- # print(request.get_host())
- # print(request.GET.get("name", None))
- return HttpResponse("OK!")
使用httpie测试:
- # GET请求带参数
- http http://127.0.0.1:8000/page/ -- name=Jan
- # PSOT请求
- http -f POST 127.0.0.1:/page/ age=
- # POST上传文件
- http -f POST http://127.0.0.1:8000/page/ dog@Desktop/dog.png
2、queryDict对象
queryDict类是python字典的子类,具有字典的所有方法,它放在django.http.QueryDict中。它用“&”分割字符传,用“=”生成键值对,从而将一个类似GET请求参数的字符串解析成一个类似字典的对象。源码如下:
- class QueryDict(MultiValueDict):
- """
- A specialized MultiValueDict which represents a query string.
- A QueryDict can be used to represent GET or POST data. It subclasses
- MultiValueDict since keys in such data can be repeated, for instance
- in the data from a form with a <select multiple> field.
- By default QueryDicts are immutable, though the copy() method
- will always return a mutable copy.
- Both keys and values set on this class are converted from the given encoding
- (DEFAULT_CHARSET by default) to str.
- """
- # These are both reset in __init__, but is specified here at the class
- # level so that unpickling will have valid values
- _mutable = True
- _encoding = None
- def __init__(self, query_string=None, mutable=False, encoding=None):
- super().__init__()
- if not encoding:
- encoding = settings.DEFAULT_CHARSET
- self.encoding = encoding
- query_string = query_string or ''
- parse_qsl_kwargs = {
- 'keep_blank_values': True,
- 'fields_limit': settings.DATA_UPLOAD_MAX_NUMBER_FIELDS,
- 'encoding': encoding,
- }
- if isinstance(query_string, bytes):
- # query_string normally contains URL-encoded data, a subset of ASCII.
- try:
- query_string = query_string.decode(encoding)
- except UnicodeDecodeError:
- # ... but some user agents are misbehaving :-(
- query_string = query_string.decode('iso-8859-1')
- for key, value in limited_parse_qsl(query_string, **parse_qsl_kwargs):
- self.appendlist(key, value)
- self._mutable = mutable
- @classmethod
- def fromkeys(cls, iterable, value='', mutable=False, encoding=None):
- """
- Return a new QueryDict with keys (may be repeated) from an iterable and
- values from value.
- """
- q = cls('', mutable=True, encoding=encoding)
- for key in iterable:
- q.appendlist(key, value)
- if not mutable:
- q._mutable = False
- return q
- @property
- def encoding(self):
- if self._encoding is None:
- self._encoding = settings.DEFAULT_CHARSET
- return self._encoding
- @encoding.setter
- def encoding(self, value):
- self._encoding = value
- def _assert_mutable(self):
- if not self._mutable:
- raise AttributeError("This QueryDict instance is immutable")
- def __setitem__(self, key, value):
- self._assert_mutable()
- key = bytes_to_text(key, self.encoding)
- value = bytes_to_text(value, self.encoding)
- super().__setitem__(key, value)
- def __delitem__(self, key):
- self._assert_mutable()
- super().__delitem__(key)
- def __copy__(self):
- result = self.__class__('', mutable=True, encoding=self.encoding)
- for key, value in self.lists():
- result.setlist(key, value)
- return result
- def __deepcopy__(self, memo):
- result = self.__class__('', mutable=True, encoding=self.encoding)
- memo[id(self)] = result
- for key, value in self.lists():
- result.setlist(copy.deepcopy(key, memo), copy.deepcopy(value, memo))
- return result
- def setlist(self, key, list_):
- self._assert_mutable()
- key = bytes_to_text(key, self.encoding)
- list_ = [bytes_to_text(elt, self.encoding) for elt in list_]
- super().setlist(key, list_)
- def setlistdefault(self, key, default_list=None):
- self._assert_mutable()
- return super().setlistdefault(key, default_list)
- def appendlist(self, key, value):
- self._assert_mutable()
- key = bytes_to_text(key, self.encoding)
- value = bytes_to_text(value, self.encoding)
- super().appendlist(key, value)
- def pop(self, key, *args):
- self._assert_mutable()
- return super().pop(key, *args)
- def popitem(self):
- self._assert_mutable()
- return super().popitem()
- def clear(self):
- self._assert_mutable()
- super().clear()
- def setdefault(self, key, default=None):
- self._assert_mutable()
- key = bytes_to_text(key, self.encoding)
- default = bytes_to_text(default, self.encoding)
- return super().setdefault(key, default)
- def copy(self):
- """Return a mutable copy of this object."""
- return self.__deepcopy__({})
- def urlencode(self, safe=None):
- """
- Return an encoded string of all query string arguments.
- `safe` specifies characters which don't require quoting, for example::
- >>> q = QueryDict(mutable=True)
- >>> q['next'] = '/a&b/'
- >>> q.urlencode()
- 'next=%2Fa%26b%2F'
- >>> q.urlencode(safe='/')
- 'next=/a%26b/'
- """
- output = []
- if safe:
- safe = force_bytes(safe, self.encoding)
- def encode(k, v):
- return '%s=%s' % ((quote(k, safe), quote(v, safe)))
- else:
- def encode(k, v):
- return urlencode({k: v})
- for k, list_ in self.lists():
- k = force_bytes(k, self.encoding)
- output.extend(encode(k, force_bytes(v, self.encoding))
- for v in list_)
- return '&'.join(output)
示例:
- from django.http import QueryDict
- # 添加django的环境配置
- import os, django
- os.environ.setdefault("DJANGO_SETTINGS_MODULE", "restful.settings")
- django.setup()
- get_vactors = "a=1&a=2&a=3&b=Jan&b=Li&c=20"
- query = QueryDict(get_vactors, mutable=True)
- # print(query)
- # 根据键生成新的QueryDict
- query_new = QueryDict.fromkeys(query, value="这个大傻子")
- # print(query_new)
- # 获取键列表、值列表、键值对列表(值列表中的最后一个元素)
- print(list(query.items())) # 生成器,获取包含键和最后一个值元素的元组的列表
- print(list(query.keys())) # dict_keys,获取键
- print(list(query.values())) # 生成器,获取每个键的最后一个元素值
- # 键值对
- print(list(query.lists())) # 获取键键值对列表
- print(dict(query)) # 转成字典,相当于query.dict()
- # 获取单个元素及列表
- alist = query.get("a")
- print(alist) # 获取最后一个元素值
- alist = query.getlist("a")
- print(alist) # 获取键对应的value,返回元素列表
- # 添加/修改键值对,必须将mutable设置为True
- query.setlist("a", [4, 5, 6])
- query.setlistdefault("d", [4,5,6])
- query.appendlist("e", ["this", "is", "append"])
- print(query)
- # 删除键值对
- query.pop("e") # 删除指定键值对
- print(query)
- query.popitem() # 删除最后一个键值对
- print(query)
3、HttpResponse
HttpResponse类用于设置响应头和响应内容,同样封装在django.http模块中。它分为实例化对象、填充设置以及返回三个部分。它同时也是其它请求响应类的父类。
- from django.http import HttpResponse
- # 添加django的环境配置
- import os, django
- os.environ.setdefault("DJANGO_SETTINGS_MODULE", "restful.settings")
- django.setup()
- # 实例化一:
- responseOne = HttpResponse("this is a http response")
- # 实例化二:
- responseTwo = HttpResponse()
- responseTwo.write("this is another http response")
- responseTwo.writelines(["this is second line", "this is third line"])
- # 设置响应头
- responseOne["Age"] = 20
- responseOne["app"] = "sample"
- del responseOne["app"]
- # 设置响应头
- responseOne["content_type"] = 'application/vnd.ms-excel'
- responseOne['Content-Disposition'] = 'attachment; filename="foo.xls"'
- responseOne.set_cookie("date", "2018-08-21", path="/page", ) # 设置cookie
- responseOne.delete_cookie("date") # 删除cookie
- # 有关对象
- print(responseOne) # HttpResponse
- print(responseOne.items()) # dict_values
- print(responseOne.cookies) # cookie
- print(responseOne.content) # 内容(字节)
- print(responseOne.charset) # 编码
- print(responseOne.status_code) # 状态码
- print(responseOne.streaming) # 是否为流
- print(responseOne.closed) # 是否已发送response
- print(responseOne.serialize()) # 序列化响应头和相应内容
- print(responseOne.serialize_headers()) # 序列化响应头
- print(responseOne.get("Age")) # 获取响应头中的某个键值对
- print(responseTwo.getvalue()) # 获取相应的内容
- # 将response设置为流数据处理
- responseTwo.readable()
- responseTwo.seekable()
- responseTwo.write("...")
其它继承HttpResponse的子类包括:
- HttpResponseRedirect # 重定向
- HttpResponsePermanentRedirect # 永久重定向
- HttpResponseNotModified #
- HttpResponseBadRequest #
- HttpResponseNotFound #
- HttpResponseForbidden #
- HttpResponseNotAllowed #
- HttpResponseGone #
- HttpResponseServerError #
4、JsonResponse
返回一个序列化的JSON对象。对于列表、字符串等,它会自动生成索引-元素JSON;对于字典,会直接生成相应的JSON。
- class JsonResponse(HttpResponse):
- """
- An HTTP response class that consumes data to be serialized to JSON.
- :param data: Data to be dumped into json. By default only ``dict`` objects
- are allowed to be passed due to a security flaw before EcmaScript 5. See
- the ``safe`` parameter for more information.
- :param encoder: Should be a json encoder class. Defaults to
- ``django.core.serializers.json.DjangoJSONEncoder``.
- :param safe: Controls if only ``dict`` objects may be serialized. Defaults
- to ``True``.
- :param json_dumps_params: A dictionary of kwargs passed to json.dumps().
- """
- def __init__(self, data, encoder=DjangoJSONEncoder, safe=True,
- json_dumps_params=None, **kwargs):
- if safe and not isinstance(data, dict):
- raise TypeError(
- 'In order to allow non-dict objects to be serialized set the '
- 'safe parameter to False.'
- )
- if json_dumps_params is None:
- json_dumps_params = {}
- kwargs.setdefault('content_type', 'application/json')
- data = json.dumps(data, cls=encoder, **json_dumps_params)
- super().__init__(content=data, **kwargs)
DjangoJSONEncoder是内置的JSON编码方式,也支持传入自己写的编码方式对数据进行序列化。
- # python manage.py shell
- from django.http import JsonResponse
- response = JsonResponse({'foo': 'bar'})
- response.content
- from django.http import JsonResponse
- from django.views.decorators.csrf import csrf_exempt
- @csrf_exempt
- def page(request):
- # lis = list(range(10))
- # return JsonResponse(lis, safe=False)
- # dic = {"name": "Jan", "age": 20}
- # return JsonResponse(dic)
- string = "this is json response"
- return JsonResponse(string, safe=False)
5、FileResponse
- from django.http import FileResponse
- response = FileResponse(open('myfile.png', 'rb'))
Django(三):HttpRequest和HttpResponse的更多相关文章
- Django中HttpRequest和HttpResponse
请求和响应对象 Django中通过使用请求和响应对象来传递系统的状态. 当请求一个页面的时候,Django就创建一个HttpRequest对象,它包含了关于请求的元数据对象,然后Django加载适当的 ...
- Django的httprequest对象和httpresponse对象
请求一张页面时,Django把请求的metadata数据包装成一个HttpRequest对象,然后Django加载合适的view方法,把这个HttpRequest 对象作为第一个参数传给view方法. ...
- Python Django 前后端数据交互 之 HttpRequest、HttpResponse、render、redirect
在使用三神装的时候,首先当然是得要导入它们: from django.shortcuts import HttpResponse, render, redirect 一.HttpRequest捕获 ...
- Django框架(五)-- 视图层:HttpRequest、HTTPResponse、JsonResponse、CBV和FBV、文件上传
一.视图函数 一个视图函数,简称视图,是一个简单的Python 函数,它接受Web请求并且返回Web响应.响应可以是一张网页的HTML内容,一个重定向,一个404错误,一个XML文档,或者一张图片. ...
- Django框架(六)—— 视图层:HttpRequest、HTTPResponse、JsonResponse、CBV和FBV、文件上传
目录 视图层 一.视图函数 二.视图层之HttpRequest对象 三.视图层之HttpResponse对象 四.视图层之JsonResponse对象 五.CBV和FBV 六.文件上传 视图层 一.视 ...
- [R]django的HTTPREQUEST对象
django的HTTPREQUEST对象 via Django使用request和response对象 当请求一张页面时,Django把请求的metadata数据包装成一个HttpRequest对象, ...
- django的HTTPREQUEST对象
Django使用request和response对象 当请求一张页面时,Django把请求的metadata数据包装成一个HttpRequest对象,然后Django加载合适的view方法,把这个Ht ...
- 冰冻三尺非一日之寒--web框架Django(三)
第二十章: django(三,多对多) 1.Django请求的生命周期 路由系统 -> 视图函数(获取模板+数据-->渲染) -> 字符串返回给用户 2. ...
- Web框架之Django_01初识(三大主流web框架、Django安装、Django项目创建方式及其相关配置、Django基础三件套:HttpResponse、render、redirect)
摘要: Web框架概述 Django简介 Django项目创建 Django基础必备三件套(HttpResponse.render.redirect) 一.Web框架概述: Python三大主流Web ...
随机推荐
- Yes,I know the way to learn Ens !
In recent years, translation has gone out of fashion as a way to learn a new language. A lot of peop ...
- IAP远程在线升级
IAP远程在线升级 在上一篇中实现了LWIP网口通讯,那么肯定要加个在线升级功能,这个功能所占用的资源很少,但在物联网中很重要也很实用.在线升级就是像手机一样,先下载好系统,然后点击升级~然后就没然后 ...
- 微信小程序 Unexpected end of JSON input/Unexpected token o in JSON at position 1
原因JSON.parse无法识别某些url中的特殊字符,所以报错 mistakes.js中 nextBtn:function(){ var nextData = this.data.dataNextI ...
- 一次对webshell的后门的查看
本文作者i春秋作家——非主流 昨天晚上突发奇想的想去看看github上面tennc的webshell收集项目中的shell有没有漏洞,比如未授权啊啥的,结果找半天都没找到...但是机缘巧合下,居然给我 ...
- Volley源码解析
说点题外话,将近三个半月没有写博客了,年初换工作,在新的公司,上班第三天开始干活,花了二十来天弄了一个项目,上线后,接着又迭代了几个版本,不知不觉,试用期过完,才稍微有几天闲时.在年初的时候,就一直在 ...
- [bug]小程序弹出层滚动穿透问题修复
如题,解决方案有两种: 1.如果弹出层没有滚动事件,就直接在蒙板和弹出层上加 catchtouchmove;(方便快捷) <template name="popup-modal&quo ...
- 浅析js中取绝对值的2种方法
1.abs() var aaa=-20; var bbb=Math.abs(aaa); 2.加减法 var aaa=-20; var bbb=-aaa
- php5数组与php7数组区别
http://ju.outofmemory.cn/entry/197064 http://www.fzb.me/2015-9-16-php7-implementation-hashtable.html ...
- JS: 数组扁平化
数组扁平化 什么是数组扁平化? 数组扁平化就是将一个多层嵌套的数组 (Arrary) 转化为只有一层. // 多层嵌套 [1, 2, [3, 4]] // 一层 [1, 2, 3, 4] 递归实现 思 ...
- 【BZOJ4916】神犇和蒟蒻 杜教筛
题目传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=4916 第一个询问即求出$\sum_{i=1}^{n} { \mu (i^2)} $,考虑 ...