目录

客户端传参的几种方式:... 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<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方法),无论clientGET还是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,DELETEdjango对这几种请求方式开启了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))

 

1.jpg

 

获取非表单类型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))

2.jpg

 

获取请求头数据:

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))

3.jpg

 

 

 

服务器端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})   #传入pydict,可自动转为json类型,会自动设置响应头的Content-Typeapplication/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请求服务器是无状态的,它的每一次请求对于服务器来说都是新的,服务器默认不会保存用户的状态数据,但很多时候,服务器需要保存用户的一些状态数据,如用户是否登录过,用户浏览过哪些商品等,解决:cookiesession

 

 

cookie

是由服务器生成的,存储在b端的k-v对数据(通常经过加密);

在响应请求时,服务器会把生成的cookie数据发给bb会自动保存(前提b林开启cookie功能);

b请求s时,会自动上传该s生成的所有cookie

每个网站只能访问到自己生成的cookie,无法访问其它网站(域)生成的cookie

4.jpg

 

djangocookie的保存和读取:

保存,通过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))

5.jpg

 

 

session

cookie是在b端保存k-v对数据,而session是在s端保存k-v对数据,重要敏感的数据(银行卡号密码等)建议存储在s端,不能通过cookie保存在b端;

session的使用依赖cookie

6.jpg

 

session数据默认保存在django项目的django_session表中,字段为sessionidb标识),session_datak-v对,dict),expire_date(过期时间);

表中一条记录,保存着一个用户所有的session健值对数据;

sessionid,浏览器标识(用户标识),代表着一个用户,通过sessionid可以找到该用户所有的session键值对数据;

 

django默认开启了session功能,settings.pyINSTALLED_APPSMIDDLEWARE

 

>python manage.py makemigrations

>python manage.py migrate   #生成django默认的表

 

djangosession的数据操作:

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秒没有活动后过期;value0,则session数据将在用户关闭b时过期;valueNone,则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_typeresponse 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

 

 

 

下载文件: