2011-09-18 42 views
14

Tôi muốn viết chế độ xem Django để phân phát nội dung biến thể dựa trên những gì được yêu cầu. Ví dụ: đối với "văn bản/xml", phân phối XML, cho "văn bản/json", phân phát JSON, v.v ... Có cách nào để xác định điều này từ đối tượng yêu cầu không? Một cái gì đó như thế này sẽ tuyệt vời:Xác định loại nội dung được yêu cầu?

def process(request): 
    if request.type == "text/xml": 
     pass 
    elif request.type == "text/json": 
     pass 
    else: 
     pass 

Có tài sản nào trên HttpRequest cho điều này không?

Trả lời

10

HttpRequest.META, cụ thể hơn HttpRequest.META.get('HTTP_ACCEPT') — và không HttpRequest.META.get('CONTENT_TYPE') như đã đề cập trước đó

+4

Tôi biết điều này là cũ, nhưng mặc dù điều này là câu trả lời được chấp nhận, nó không phải là chính xác . Như đã đề cập trong bình luận của Jan dưới đây, phương thức đúng là tiêu đề 'Accept', có thể truy cập thông qua 'HttpRequest.META.get ('HTTP_ACCEPT')'. –

+2

Bạn có thể thực hiện dự phòng, để xử lý cả hai trường hợp (cộng với mặc định): 'request.META.get ('HTTP_ACCEPT', request.META.get ('CONTENT_TYPE', 'application/your_default'))' –

16

'Content-Type' tiêu đề chỉ ra loại phương tiện gửi yêu cầu HTTP. Điều này được sử dụng cho các yêu cầu có nội dung (POST, PUT).

'Loại nội dung' không được sử dụng để biểu thị định dạng phản hồi ưa thích, tiêu đề 'Chấp nhận' phục vụ mục đích này. Để truy cập vào nó trong Django sử dụng: HttpRequest.META.get ('HTTP_ACCEPT')

See more detailed description of these headers

1

Như đã nói trong câu trả lời khác, thông tin này nằm trong tiêu đề Accept yêu cầu. Có sẵn trong yêu cầu dưới dạng HttpRequest.META['HTTP_ACCEPT'].

Tuy nhiên, không chỉ có một loại nội dung được yêu cầu và tiêu đề này thường là danh sách các loại nội dung được chấp nhận/ưa thích. Danh sách này có thể hơi khó chịu để khai thác đúng cách. Đây là một chức năng mà không được công việc:

import re 

def get_accepted_content_types(request): 
    def qualify(x): 
     parts = x.split(';', 1) 
     if len(parts) == 2: 
      match = re.match(r'(^|;)q=(0(\.\d{,3})?|1(\.0{,3})?)(;|$)', 
          parts[1]) 
      if match: 
       return parts[0], float(match.group(2)) 
     return parts[0], 1 

    raw_content_types = request.META.get('HTTP_ACCEPT', '*/*').split(',') 
    qualified_content_types = map(qualify, raw_content_types) 
    return (x[0] for x in sorted(qualified_content_types, 
           key=lambda x: x[1], reverse=True)) 

Ví dụ, nếu request.META['HTTP_ACCEPT'] bằng "text/html;q=0.9,application/xhtml+xml,application/xml;q=0.8,*/*;q=0.7". Điều này sẽ trả về: ['application/xhtml+xml', 'text/html', 'application/xml', '*/*'](không thực sự, vì nó trả về một trình tạo).

Sau đó, bạn có thể lặp qua danh sách kết quả để chọn loại nội dung đầu tiên mà bạn biết cách phản hồi đúng cách.

Lưu ý rằng chức năng này sẽ hoạt động trong hầu hết các trường hợp nhưng không xử lý các trường hợp như q=0 có nghĩa là "Không được chấp nhận".

Nguồn: HTTP Accept header specificationQuality Values specification

+0

Câu trả lời này nên thay thế câu trả lời hàng đầu và được chấp nhận. – user73657

1

trong django 1.10, bây giờ bạn có thể sử dụng, request.content_type, như đã đề cập ở đây trong their doc

Các vấn đề liên quan