目录
客户端传参的几种方式:... 1
服务器端view中,获取url路径传递的参数:... 2
服务器端view中,获取query string参数:... 2
服务器端view中,获取请求体数据:... 2
获取Form Data()键值对:... 3
获取非表单类型None-Form Data,如json类型:... 3
获取请求头数据:... 4
服务器端view中,响应:... 5
服务器端view中,cookie|session:... 6
cookie:... 6
session:... 7
view:... 8
返回404:... 9
自定义错误view:... 9
render() 9
redirect() 10
get_object_or_404() 10
get_list_or_404() 11
decorator:... 12
HttpRequest()、HttpResponse() 12
send_mail() 13
导出csv:... 14
上传文件:... 14
下载文件:... 15
客户端传参的几种方式:
1、通过URL路径传递,如http://ip:port/news/1/2,两个参数,新闻类型id和页码;
2、通过query string传递,如http://ip:port/news?category=1&page=2;
3、通过body请求体传递,又可根据数据格式分为k-v对、form数据、非form数据(json|xml);
4、通过http header传递;
服务器端view中,获取url路径传递的参数:
解决:
在配置URL时,用正则匹配url中的参数;
用py的正则分组,可以对组命名(命名参数-关键字参数),也可不命名(未命名参数-位置参数);
匹配成功后,django会自动匹配成功的值,作为方法的参数传递到视图函数中;
例1(未命名参数-位置参数):
url(r'^news/(\d+)/(\d+)$', users.views.news),
def news(request, a, b):
return HttpResponse('news: {} {}'.format(a,b))
例2(命名参数-关键字参数):
url(r'^news/(?P
def news(request, category, page):
return HttpResponse('news: {} {}'.format(category, page)
服务器端view中,获取query string参数:
url(r'^news/$', users.views.news)
def news(request):
category = request.GET.get('category') #query string不区分请求方式(HTTP方法),无论client用GET还是POST请求,都可通过request.GET获取到queyr string
page = request.GET.get('page')
return HttpResponse('query string is: {}/{}'.format(category, page))
服务器端view中,获取请求体数据:
请求体数据格式可以是form类型字符串、json类型字符串、xml类型字符串,要区别对待;
可发送请求体数据的HTPP方法有,POST,PUT,PATCH,DELETE;django对这几种请求方式开启了CSRF安全防护,为方便测试,可将对应的中间件注释,'django.middleware.csrf.CsrfViewMiddleware',;
获取Form Data()键值对:
url(r'^news/$', users.views.news)
def news(request):
category = request.POST.get('category') #request.POST只能用来获取POST方式的请求体表单数据或k-v对数据;如果为非请求提交的请求体数据,或是请求体数据类型为非表单或非k-v对数据,则要通过request.body属性获取,获取到后再自己解析
page = request.POST.get('page')
return HttpResponse('form: {} {}'.format(category, page))
获取非表单类型None-Form Data,如json类型:
url(r'^news/$', users.views.news)
def news(request):
json_str = request.body
dict_data = json.loads((json_str)) #解析json
category = dict_data.get('category')
page = dict_data.get('page')
return HttpResponse('json: {} {}'.format(category, page))
获取请求头数据:
url(r'^news/$', users.views.news)
def news(request):
a = request.META.get('HTTP_A')
b = request.META.get('HTTP_B')
return HttpResponse('header: {} {}'.format(category, page))
服务器端view中,响应:
视图必须返回一个HttpResponse对象(或其子类),可将要返回的字符串传给HttpResponse对象再返回;
HttpRequest对象由django创建,HttpResponse对象由开发人员创建;
django.http.HttpResponse常用子类:django.http.HttpResponseRedirect(重定向),django.http.JsonResponse(返回json数据);
django.shortcuts.redirect(不返回具体显示内容给client,让client重新请求返回的地址,获取内容);
def news(request):
json_str = '{"name": "jowin"}'
return HttpResponse(json_str, content_type='application/json', status=400)
def news(request):
response = HttpResponse('my name is jowin')
response['name'] = 'jowin' #响应头设置(可直接将HttpResponse对象当作字典进行响应头键值对的设置)
return response
def news(request):
return JsonResponse({'name': 'jowin}) #传入py的dict,可自动转为json类型,会自动设置响应头的Content-Type为application/json;另,可传入非dict数据,前提要把safe=False
注,django.http.JsonResponse源码:
class JsonResponse(HttpResponse):
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(JsonResponse, self).__init__(content=data, **kwargs)
def news(request):
return redirect('/index')
服务器端view中,cookie|session:
b请求服务器是无状态的,它的每一次请求对于服务器来说都是新的,服务器默认不会保存用户的状态数据,但很多时候,服务器需要保存用户的一些状态数据,如用户是否登录过,用户浏览过哪些商品等,解决:cookie或session;
cookie:
是由服务器生成的,存储在b端的k-v对数据(通常经过加密);
在响应请求时,服务器会把生成的cookie数据发给b,b会自动保存(前提b林开启cookie功能);
b请求s时,会自动上传该s生成的所有cookie;
每个网站只能访问到自己生成的cookie,无法访问其它网站(域)生成的cookie;
django中cookie的保存和读取:
保存,通过HttpResponse响应对象的set_cookie方法;
读取,通过HttpRequest请求对象的COOKIES属性(dict);
例:
urlpatterns = [
url(r'set_cookie$', users.views.set_cookie),
url(r'^get_cookie$', user.views.get_cookie),
]
def set_cookie(request):
response = HttpResponse('save cookie')
response.set_cookie('user_id', 10)
response.set_cookie('user_name', 'jowin')
return response
def get_cookie(request):
user_id = request.COOKIES.get('user_id')
user_name = request.COOKIES.get('user_name')
return HttpResponse('{} {}'.format(user_id, user_name))
session:
cookie是在b端保存k-v对数据,而session是在s端保存k-v对数据,重要敏感的数据(银行卡号密码等)建议存储在s端,不能通过cookie保存在b端;
session的使用依赖cookie;
session数据默认保存在django项目的django_session表中,字段为sessionid(b标识),session_data(k-v对,dict),expire_date(过期时间);
表中一条记录,保存着一个用户所有的session健值对数据;
sessionid,浏览器标识(用户标识),代表着一个用户,通过sessionid可以找到该用户所有的session键值对数据;
django默认开启了session功能,settings.py中INSTALLED_APPS和MIDDLEWARE;
>python manage.py makemigrations
>python manage.py migrate #生成django默认的表
django中session的数据操作:
request.session['k'] = v #保存,request.session属性(django.contrib.sessions.backends.db.SessionStore)
request.session.get('k', default_v) #读取
del request.session['k'] #删除
request.session.flush() #删除一条记录
request.session.clear() #清空字段中的session健值对数据
request.session.set_expiry(value) #value为整数,则session数据将在value秒没有活动后过期;value为0,则session数据将在用户关闭b时过期;value为None,则session数据将在2周后过期
view:
返回404:
from django.http import HttpResponse, HttpResponseNotFound
return HttpResponse('Not found', status=404)
或
return HttpResonseNotFound('Not found')
注:django.http
__all__ = [
'SimpleCookie', 'parse_cookie', 'HttpRequest', 'QueryDict',
'RawPostDataException', 'UnreadablePostError',
'HttpResponse', 'StreamingHttpResponse', 'HttpResponseRedirect',
'HttpResponsePermanentRedirect', 'HttpResponseNotModified',
'HttpResponseBadRequest', 'HttpResponseForbidden', 'HttpResponseNotFound',
'HttpResponseNotAllowed', 'HttpResponseGone', 'HttpResponseServerError',
'Http404', 'BadHeaderError', 'JsonResponse', 'FileResponse',
]
自定义错误view:
urls.py
handler400 = 'mysite.views.my_custom_bad_request_view'
handler403 = 'mysite.views.my_custom_permission_denied_view'
handler404 = 'mysite.views.my_custom_page_not_found_view'
handler500 = 'mysite.views.my_custom_error_view'
render(),from django.shortcuts import render:
def render(request, template_name, context=None, content_type=None, status=None, using=None):
"""
Returns a HttpResponse whose content is filled with the result of calling
django.template.loader.render_to_string() with the passed arguments.
"""
content = loader.render_to_string(template_name, context, request, using=using)
return HttpResponse(content, content_type, status)
另,render_to_response(),老版本1.6用;
args:
request,the request object used to generate this response;
template_name,模板名称,可以是列表,会使用先找到的那个(app中的templates/app_name/下存放模板,避免找到其它app的模板);
optional argument:
context,渲染模板的context字典,默认是{};
content_type,response MIME type,默认用DEFAULT_CONTENT_TYPE;
status,the status code for the response. defaults to 200;
using,the name of a template engine to use for loading the template,指定模板引擎;
一般前3个参数必须指定;
redirect(),from django.shortcuts import redirect
def redirect(to, *args, **kwargs):
"""
Returns an HttpResponseRedirect to the appropriate URL for the arguments
passed.
The arguments could be:
* A model: the model's `get_absolute_url()` function will be called.
* A view name, possibly with arguments: `urls.reverse()` will be used
to reverse-resolve the name.
* A URL, which will be used as-is for the redirect location.
By default issues a temporary redirect; pass permanent=True to issue a
permanent redirect
"""
if kwargs.pop('permanent', False):
redirect_class = HttpResponsePermanentRedirect
else:
redirect_class = HttpResponseRedirect
return redirect_class(resolve_url(to, *args, **kwargs))
例:
return redirect(object) #object=MyModel.objects.get(..)
return redirect('view_name', foo='bar')
return redirect('/some/url/')
return redirect('https://example.com', permanent=True) #永久重定向
get_object_or_404(),from django.shortcuts import get_object_or_404:
def get_object_or_404(klass, *args, **kwargs):
"""
Uses get() to return an object, or raises a Http404 exception if the object
does not exist.
klass may be a Model, Manager, or QuerySet object. All other passed
arguments and keyword arguments are used in the get() query.
Note: Like with get(), an MultipleObjectsReturned will be raised if more than one
object is found.
"""
queryset = _get_queryset(klass)
try:
return queryset.get(*args, **kwargs)
except AttributeError:
klass__name = klass.__name__ if isinstance(klass, type) else klass.__class__.__name__
raise ValueError(
"First argument to get_object_or_404() must be a Model, Manager, "
"or QuerySet, not '%s'." % klass__name
)
except queryset.model.DoesNotExist:
raise Http404('No %s matches the given query.' % queryset.model._meta.object_name)
例:
def detail(request, question_id):
# try:
# question = Question.objects.get(id=question_id)
# except Question.DoesNotExist:
# return HttpResponse('Not Found', status=404)
question = get_object_or_404(Question, pk=question_id) #以上4行等价于此行
return render(request, 'polls/detail.html', {'question': question})
get_list_or_404(),from django.shortcuts import get_list_or_404:
def get_list_or_404(klass, *args, **kwargs):
"""
Uses filter() to return a list of objects, or raise a Http404 exception if
the list is empty.
klass may be a Model, Manager, or QuerySet object. All other passed
arguments and keyword arguments are used in the filter() query.
"""
queryset = _get_queryset(klass)
try:
obj_list = list(queryset.filter(*args, **kwargs))
except AttributeError:
klass__name = klass.__name__ if isinstance(klass, type) else klass.__class__.__name__
raise ValueError(
"First argument to get_list_or_404() must be a Model, Manager, or "
"QuerySet, not '%s'." % klass__name
)
if not obj_list:
raise Http404('No %s matches the given query.' % queryset.model._meta.object_name)
return obj_list
reverse()、reverse_lazy(),from django.core.urlresolvers import reverse, reverse_lazy:
def reverse(viewname, urlconf=None, args=None, kwargs=None, current_app=None):
it is useful for when you need to use a URL reversal before your project's URLconf is loaded.
decorator:
django provides several decorators that can be applied to views to support various HTTP features.
from django.views.decorators.http import require_http_methods, require_GET, require_POST, require_safe
from django.views.decorators.gzip import gzip_page
from django.views.decorators.cache import cache_control, never_cache
login_required()
transaction.atomic
HttpRequest()、HttpResponse(),from django.http import HttpRequest, HttpResponse
class HttpRequest(object):
"""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
class HttpResponse(HttpResponseBase):
"""
An HTTP response class with a string as content.
This content that can be read, appended to or replaced.
"""
streaming = False
def __init__(self, content=b'', *args, **kwargs):
super(HttpResponse, self).__init__(*args, **kwargs)
# Content is a bytestring. See the `content` property methods.
self.content = content
@property
def content(self):
return b''.join(self._container)
send_mail(),发送邮件,from django.core.mail import send_mail:
def send_mail(subject, message, from_email, recipient_list,
fail_silently=False, auth_user=None, auth_password=None,
connection=None, html_message=None):
"""
Easy wrapper for sending a single message to a recipient list. All members
of the recipient list will see the other recipients in the 'To' field.
If auth_user is None, the EMAIL_HOST_USER setting is used.
If auth_password is None, the EMAIL_HOST_PASSWORD setting is used.
Note: The API for this method is frozen. New code wanting to extend the
functionality should use the EmailMessage class directly.
"""
注:
recipient_list是一list;
导出csv:
import csv
from django.http import HttpResponse
def some_view(request):
# Create the HttpResponse object with the appropriate CSV header.
response = HttpResponse(content_type='text/csv')
response['Content-Disposition'] = 'attachment; filename="somefilename.csv"'
writer = csv.writer(response)
writer.writerow(['First row', 'Foo', 'Bar', 'Baz'])
writer.writerow(['Second row', 'A', 'B', 'C', '"Testing"', "Here's a quote"])
return response
上传文件:
from django.shortcuts import render
from django.http import HttpResponse
下载文件: