2012-06-27 28 views
18

Tôi muốn đặt cookie nếu người dùng đăng nhập hay không.Django: đối tượng WSGIRequest 'không có thuộc tính' người dùng 'trên một số trang?

My Middleware:

class UserStatus(object): 
    def process_response(self,request,response): 
     user_status = 1 if request.user.is_authenticated() else 0 
     max_age = (20)*52*7*24*60*60 # 20 years (After expiry, cookie gets deleted) 
     response.set_cookie(user_status_cookie,user_status,max_age) 
     return response 

Thêm vào MIDDLEWARE_CLASSES trong settings.py ở cuối.

Vấn đề:

  • Lỗi: đối tượng 'WSGIRequest' không có thuộc tính 'user'
  • Tại sao, khi tôi có xác thực và middlewares phiên hoạt động chưa?
  • Ngoài ra, một số trang hoạt động trơn tru khi một số trang cung cấp lỗi này.
  • Tôi đang làm gì sai?

Vui lòng trợ giúp.

Trả lời

12

Theo FineManual:

During the response phases (process_response() and process_exception() middleware), the classes are applied in reverse order, from the bottom up

Vì vậy, tôi muốn nói bạn nên thêm middleware của bạn trước các auth và middlewares phiên (giả sử nó chỉ xử lý response).

Điều này đang được nói, tôi hơi bối rối bởi thực tế là bạn chỉ gặp lỗi trên một số trang ???

+4

Tôi đoán một số trang không được nối thêm dấu gạch chéo. – Babu

9

làm bạn phải hoạt động trung gian này ?:

'django.contrib.auth.middleware.AuthenticationMiddleware' 

Và đây chạy middleware trước middleware của bạn?

22

Ran vào cùng một vấn đề thời gian gần đây, và thấy rằng nó đã xảy ra khi một url đang truy cập mà không có dấu gạch chéo, và các thiết lập APPEND_SLASH được thiết lập là true:


Django xử lý yêu cầu ban đầu

  • CommonMiddleware.process_request
    • chuyển hướng để NEWURL, trong đó có các dấu gạch chéo
  • process_response vẫn chạy trong tùy chỉnh middleware
    • yêu cầu.người sử dụng không có mặt
  • HTTP 301

Django sau đó xử lý yêu cầu của url với trailing slash

  • process_response được chạy trong middleware tùy chỉnh
    • request.user là bây giờ có mặt

Bất kỳ ai biết tại sao một số thuộc tính chính (người dùng và phiên) không thể truy cập trong process_response sau khi chuyển hướng vĩnh viễn?

+0

Về lý do tại sao: Đó là vì CommonMiddleware trả về giá trị 'HttpResponse' trước khi' AuthenticationMiddleware.process_request' có cơ hội chạy, trong đó thử 'AuthenticationMiddleware'. "Nếu nó trả về một đối tượng HttpResponse, Django sẽ không bận tâm gọi bất kỳ yêu cầu, lượt xem hoặc phần mềm trung gian ngoại lệ nào khác hoặc chế độ xem thích hợp; nó sẽ áp dụng phần mềm trung gian phản hồi cho HttpResponse đó và trả lại kết quả." —https: //docs.djangoproject.com/en/1.7/topics/http/middleware/#process-request –

13

Vì vậy, nó đã làm với APPEND_SLASH được áp dụng với qua một chuyển hướng bởi Django Common Middleware, ngăn ngừa sự process_request() trong AuthenticationMiddleware (có thêm thuộc tính user) từ được chạy nhưng bạn process_response vẫn được chạy.

Sau đây là cách Django Process Middleware thực sự hoạt động (từ django/core/handlers/base.py trong Django 1,6)

  1. Bạn yêu cầu một URL mà không có một dấu gạch chéo. Vì vậy, yourdomain.com/view. Điều này bắt đầu dòng trung gian.
  2. Khi yêu cầu đạt đến CommonMiddleware, phần mềm trung gian sẽ thấy rằng không có dấu gạch chéo và trả lại http.HttpResponsePermanentRedirect(newurl). Này ngay lập tức dừng lại thêm bất kỳ process_requests từ được chạy, trong đó có một trong AuthenticationMiddleware rằng thêm user thuộc tính để request
  3. CommonMiddleware không trở về một ngoại lệ (bao gồm Http404), django bây giờ sẽ lấy phản hồi từ middleware và chạy nó thông qua EVERY process_response() trong MỌI phần mềm trung gian được liệt kê trong MIDDLEWARE_CLASSES, bất kể phần mềm trung gian của process_request() có cơ hội để chạy hay không.

Cách thực chỉ để sửa lỗi này là một trong hai di chuyển mã của bạn thành một phương pháp process_request() nằm sau AuthenticationMiddleware trong MIDDLEWARE_CLASSES hoặc phát hiện qua hasattr() nếu đối tượng request có một thuộc tính user.

+3

Điều này thật tuyệt! Ứng dụng của tôi đã hoạt động khi tôi đặt phần mềm trung gian theo thứ tự sau: ('django.contrib.auth.middleware.AuthenticationMiddleware', 'MyMiddleware', 'django.middleware.common.CommonMiddleware') – Temuz

4

Tôi đã có một vấn đề tương tự, một số trang của tôi không có người sử dụng trong yêu cầu như vậy trong middleware của tôi, tôi làm một kiểm tra nhanh chóng

if not hasattr(request, 'user'): 
    return response 
0

Có thể được một ngoại lệ huy động trong một số middleware hoặc bất kỳ mã khác chạy trước AuthenticationMiddleware của django (có trách nhiệm gán .user cho đối tượng yêu cầu).

Sau đó, sẽ có một AttributeError khi truy cập biến .user.

Ví dụ: bất kỳ ngoại lệ nào được kích hoạt trước khi AuthenticationMiddleware có cơ hội chạy có thể làm cho chế độ xem lỗi thực thi. Bạn sẽ nhận được lỗi như được đề cập trong tiêu đề của câu hỏi, nếu chế độ xem lỗi phụ thuộc vào request.user.

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