目錄
服務器端view中,獲取query string參數:... 2
獲取非表單類型None-Form Data,如json類型:... 3
服務器端view中,cookie|session:... 6
HttpRequest()、HttpResponse() 12
客戶端傳參的幾種方式:
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<category>\d+)/(?P<page>\d+)$', user.views.news),
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
下載文件: