Django之 Views組件

本節內容

 

  • 路由系統
  • models模型
  • admin 
  • views視圖
  • template模板

 

我們已經學過了基本的view寫法

單純返回字符串

1
2
3
4
5
6
7
8
def current_datetime(request):
    now = datetime.datetime.now()
    html = "<html><body>It is now %s.</body></html>" % now
    return HttpResponse(html)
    #return HttpResponseNotFound('<h1>Page not found</h1>')
 
    # Return a "created" (201) response code.
    #return HttpResponse(status=201)

返回html文件  

1
2
3
4
5
6
def detail(request, poll_id):
    try:
        = Poll.objects.get(pk=poll_id)
    except Poll.DoesNotExist:
        raise Http404("Poll does not exist")
    return render(request, 'polls/detail.html', {'poll': p}) 

 

加裝飾器

1
2
3
4
5
6
@login_required
def user_list(request):
     
    users = models.Account.objects.all()
     
    return render(request,'account.html',{'account_list':users})

只允許特定方法

1
2
3
4
5
6
7
from django.views.decorators.http import require_http_methods
 
@require_http_methods(["GET""POST"])
def my_view(request):
    # I can assume now that only GET or POST requests make it this far
    # ...
    pass

  

  

HttpRequest 對象

我們知道每個視圖函數的request參數這個東西,但一直沒正式講,它到底是個什麼樣的存在?  

每一個用戶請求在到達視圖函數的同時,django會自動創建一個HttpRequest對象並把這個對象當做第一個參數傳給要調用的views方法,HttpRequest對象裏封裝了本次請求所涉及的用戶瀏覽器端數據、服務器端數據等,在views裏可以通過request對象來調取相應的屬性。

HttpRequest.scheme

A string representing the scheme of the request (http or https usually).

 

HttpRequest.path
A string representing the full path to the requested page, not including the scheme or domain.

Example: "/music/bands/the_beatles/"


HttpRequest.method
A string representing the HTTP method used in the request

1
2
3
4
if request.method == 'GET':
    do_something()
elif request.method == 'POST':
    do_something_else()

 


HttpRequest.content_type
A string representing the MIME type of the request, parsed from the CONTENT_TYPE header.

MIME (Multipurpose Internet Mail Extensions) 是描述消息內容類型的因特網標準。

MIME 消息能包含文本、圖像、音頻、視頻以及其他應用程序專用的數據。

 

HttpRequest.GET
A dictionary-like object containing all given HTTP GET parameters. See the QueryDict documentation below.

HttpRequest.POST
HttpRequest.COOKIES
A dictionary containing all cookies. Keys and values are strings.

HttpRequest.FILES
A dictionary-like object containing all uploaded files. Each key in FILES is the name from the <input type="file" name="" />. Each value in FILES is an UploadedFile.

FILES will only contain data if the request method was POST and the <form> that posted to the request had enctype="multipart/form-data". Otherwise, FILES will be a blank dictionary-like object.

HttpRequest.META

A dictionary containing all available HTTP headers. Available headers depend on the client and server, but here are some examples:

  • CONTENT_LENGTH – The length of the request body (as a string).
  • CONTENT_TYPE – The MIME type of the request body.
  • HTTP_ACCEPT – Acceptable content types for the response.
  • HTTP_ACCEPT_ENCODING – Acceptable encodings for the response.
  • HTTP_ACCEPT_LANGUAGE – Acceptable languages for the response.
  • HTTP_HOST – The HTTP Host header sent by the client.
  • HTTP_REFERER – The referring page, if any.
  • HTTP_USER_AGENT – The client’s user-agent string.
  • QUERY_STRING – The query string, as a single (unparsed) string.
  • REMOTE_ADDR – The IP address of the client.
  • REMOTE_HOST – The hostname of the client.
  • REMOTE_USER – The user authenticated by the Web server, if any.
  • REQUEST_METHOD – A string such as "GET" or "POST".
  • SERVER_NAME – The hostname of the server.
  • SERVER_PORT – The port of the server (as a string).

 

Attributes set by middleware

Some of the middleware included in Django’s contrib apps set attributes on the request. If you don’t see the attribute on a request, be sure the appropriate middleware class is listed in MIDDLEWARE.

HttpRequest.session

From the SessionMiddleware: A readable and writable, dictionary-like object that represents the current session.

HttpRequest.user
  From the AuthenticationMiddleware: An instance of AUTH_USER_MODEL representing the currently logged-in user. If the user isn’t currently logged in, user will be set to an instance of AnonymousUser. You can tell them apart with is_authenticated, like so:

1
2
3
4
if request.user.is_authenticated:
... # Do something for logged-in users.
else:
... # Do something for anonymous users.

 

Methods 

除了屬性,HttpRequest對象還帶有很多方法

HttpRequest.get_host()

返回網站服務器地址,Example: "127.0.0.1:8000"

HttpRequest.get_port()

返回服務器主機端口


HttpRequest.get_full_path()
Returns the path, plus an appended query string, if applicable.

Example: "/music/bands/the_beatles/?print=true"

HttpRequest.build_absolute_uri(location)
Returns the absolute URI form of location. If no location is provided, the location will be set to request.get_full_path().

If the location is already an absolute URI, it will not be altered. Otherwise the absolute URI is built using the server variables available in this request.

Example: "https://example.com/music/bands/the_beatles/?print=true"

 

HttpRequest.is_secure()
Returns True if the request is secure; that is, if it was made with HTTPS.

HttpRequest.is_ajax()
判斷是否ajax請求

 

HttpResponse objects

class HttpResponse[source]

In contrast to HttpRequest objects, which are created automatically by Django, HttpResponse objects are your responsibility. Each view you write is responsible for instantiating, populating, and returning an HttpResponse.

The HttpResponse class lives in the django.http module.

Usage

Passing strings

Typical usage is to pass the contents of the page, as a string, to the HttpResponse constructor:

>>> from django.http import HttpResponse
>>> response = HttpResponse("Here's the text of the Web page.")
>>> response = HttpResponse("Text only, please.", content_type="text/plain")

But if you want to add content incrementally, you can use response as a file-like object:

>>> response = HttpResponse()
>>> response.write("<p>Here's the text of the Web page.</p>")
>>> response.write("<p>Here's another paragraph.</p>")

Telling the browser to treat the response as a file attachment

To tell the browser to treat the response as a file attachment, use the content_type argument and set the Content-Disposition header. For example, this is how you might return a Microsoft Excel spreadsheet:

1
2
>>> response = HttpResponse(my_data, content_type='application/vnd.ms-excel')
>>> response['Content-Disposition'= 'attachment; filename="foo.xls"'

Attributes

HttpResponse.content

A bytestring representing the content, encoded from a string if necessary.

HttpResponse.charset

A string denoting the charset in which the response will be encoded. If not given at HttpResponse instantiation time, it will be extracted from content_type and if that is unsuccessful, the DEFAULT_CHARSET setting will be used.

HttpResponse.status_code

The HTTP status code for the response.

Unless reason_phrase is explicitly set, modifying the value of status_code outside the constructor will also modify the value of reason_phrase.

HttpResponse.reason_phrase

The HTTP reason phrase for the response. It uses the HTTP standard’s default reason phrases.

Unless explicitly set, reason_phrase is determined by the value of status_code.

HttpResponse.streaming

This is always False.

This attribute exists so middleware can treat streaming responses differently from regular responses.

HttpResponse.closed

True if the response has been closed.

  

Methods

HttpResponse.__init__(content=''content_type=Nonestatus=200reason=Nonecharset=None)[source]

Instantiates an HttpResponse object with the given page content and content type.

content should be an iterator or a string. If it’s an iterator, it should return strings, and those strings will be joined together to form the content of the response. If it is not an iterator or a string, it will be converted to a string when accessed.

content_type is the MIME type optionally completed by a character set encoding and is used to fill the HTTP Content-Typeheader. If not specified, it is formed by the DEFAULT_CONTENT_TYPE and DEFAULT_CHARSET settings, by default: “text/html; charset=utf-8”.

status is the HTTP status code for the response.

reason is the HTTP response phrase. If not provided, a default phrase will be used.

charset is the charset in which the response will be encoded. If not given it will be extracted from content_type, and if that is unsuccessful, the DEFAULT_CHARSET setting will be used.

HttpResponse.set_cookie(keyvalue=''max_age=Noneexpires=Nonepath='/'domain=Nonesecure=Nonehttponly=False)

Sets a cookie. 

  • max_age should be a number of seconds, or None (default) if the cookie should last only as long as the client’s browser session. If expires is not specified, it will be calculated.

  • expires should either be a string in the format "Wdy, DD-Mon-YY HH:MM:SS GMT" or a datetime.datetime object in UTC. If expires is a datetime object, the max_age will be calculated.

  • Use domain if you want to set a cross-domain cookie. For example, domain="example.com" will set a cookie that is readable by the domains www.example.com, blog.example.com, etc. Otherwise, a cookie will only be readable by the domain that set it.

  • Use httponly=True if you want to prevent client-side JavaScript from having access to the cookie.

    HTTPOnly is a flag included in a Set-Cookie HTTP response header. It is not part of the RFC 2109 standard for cookies, and it isn’t honored consistently by all browsers. However, when it is honored, it can be a useful way to mitigate the risk of a client-side script from accessing the protected cookie data.

HttpResponse.delete_cookie(keypath='/'domain=None)

Deletes the cookie with the given key. Fails silently if the key doesn’t exist.

Due to the way cookies work, path and domain should be the same values you used in set_cookie() – otherwise the cookie may not be deleted.

 

HttpResponse subclasses

Django includes a number of HttpResponse subclasses that handle different types of HTTP responses. Like HttpResponse, these subclasses live in django.http.

class HttpResponseRedirect[source]

The first argument to the constructor is required – the path to redirect to. This can be a fully qualified URL (e.g. 'https://www.yahoo.com/search/'), an absolute path with no domain (e.g. '/search/'), or even a relative path (e.g. 'search/'). In that last case, the client browser will reconstruct the full URL itself according to the current path. See HttpResponse for other optional constructor arguments. Note that this returns an HTTP status code 302.

url

This read-only attribute represents the URL the response will redirect to (equivalent to the Location response header).

class HttpResponsePermanentRedirect[source]

Like HttpResponseRedirect, but it returns a permanent redirect (HTTP status code 301) instead of a “found” redirect (status code 302).

class HttpResponseNotModified[source]

The constructor doesn’t take any arguments and no content should be added to this response. Use this to designate that a page hasn’t been modified since the user’s last request (status code 304).

class HttpResponseBadRequest[source]

Acts just like HttpResponse but uses a 400 status code.

class HttpResponseNotFound[source]

Acts just like HttpResponse but uses a 404 status code.

class HttpResponseForbidden[source]

Acts just like HttpResponse but uses a 403 status code.

class HttpResponseNotAllowed[source]

Like HttpResponse, but uses a 405 status code. The first argument to the constructor is required: a list of permitted methods (e.g. ['GET', 'POST']).

class HttpResponseGone[source]

Acts just like HttpResponse but uses a 410 status code.

class HttpResponseServerError[source]

Acts just like HttpResponse but uses a 500 status code.

 

CBV(Class based views)

Python是一個面向對象的編程語言,如果只用函數來開發,有很多面向對象的優點就錯失了(繼承、封裝、多態)。所以Django在後來加入了CBV(Class-Based-View)。CBV就是在視圖裏使用類處理請求。

即可以讓我們用類寫View。這樣做的優點主要下面兩種:

  • 提高了代碼的複用性,可以使用面嚮對象的技術,比如Mixin(多繼承)
  • 可以用不同的函數針對不同的HTTP方法處理,而不是通過很多if判斷,提高代碼可讀性
1
2
3
4
5
6
7
from django.http import HttpResponse
from django.views import View
 
class MyView(View):
    def get(self, request):
        # <view logic>
        return HttpResponse('result')

Django的url收到請求後,是需要把這個請求分配給一個可調用的函數的,而不是一個class。針對這個問題,class-based view提供了一個as_view()靜態方法(也就是類方法),調用這個方法,會創建一個類的實例,然後通過實例調用dispatch()方法,dispatch()方法會根據request的method的不同調用相應的方法來處理request(如get() , post()等)。到這裏,這些方法和function-based view差不多了,要接收request,得到一個response返回。如果方法沒有定義,會拋出HttpResponseNotAllowed異常。  

在url中,就這麼寫:

1
2
3
4
5
6
7
# urls.py
from django.urls import path
from myapp.views import MyView
 
urlpatterns = [
    path('about/', MyView.as_view()),
]

 

cbv視圖屬性設置

類的屬性可以通過兩種方法設置,第一種是常見的Python的方法,可以被子類覆蓋。

1
2
3
4
5
6
7
8
from django.http import HttpResponse
from django.views import View
 
class GreetingView(View):
    greeting = "Good Day"
 
    def get(self, request):
        return HttpResponse(self.greeting)

子類中只需繼承

1
2
class MorningGreetingView(GreetingView):
    greeting = "Morning to ya"

第二種方法,你也可以在url中指定類的屬性:

在url中設置類的屬性Python

1
2
3
urlpatterns = [
    path('about/', GreetingView.as_view(greeting="G'day")),
]

  

Decorating the class

To decorate every instance of a class-based view, you need to decorate the class definition itself. To do this you apply the decorator to the dispatch() method of the class.

A method on a class isn’t quite the same as a standalone function, so you can’t just apply a function decorator to the method – you need to transform it into a method decorator first. The method_decorator decorator transforms a function decorator into a method decorator so that it can be used on an instance method. For example:

from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator
1
2
3
4
5
6
<br>class MyView(View):
 
    @method_decorator(login_required)
    def dispatch(self*args, **kwargs):
        #print('----')
        return super().dispatch(*args, **kwargs)

Or, more succinctly, you can decorate the class instead and pass the name of the method to be decorated as the keyword argument name:

1
2
3
4
5
6
7
@method_decorator(login_required,name='dispatch')
class MyView(View):
 
    def get(self,request):
 
        print("get request...",request)
        return HttpResponse("result")

  

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章