Django: Chuyển hướng đến trang trước sau khi đăng nhập


175

Tôi đang cố gắng xây dựng một trang web đơn giản với chức năng đăng nhập rất giống với trang web ở đây trên SO. Người dùng sẽ có thể duyệt trang web dưới dạng người dùng ẩn danh và sẽ có một liên kết đăng nhập trên mỗi trang. Khi nhấp vào liên kết đăng nhập, người dùng sẽ được đưa đến biểu mẫu đăng nhập. Sau khi đăng nhập thành công, người dùng sẽ được đưa trở lại trang từ nơi anh ta nhấp vào liên kết đăng nhập ở vị trí đầu tiên. Tôi đoán rằng bằng cách nào đó tôi phải chuyển url của trang hiện tại sang chế độ xem xử lý biểu mẫu đăng nhập nhưng tôi thực sự không thể làm cho nó hoạt động được.

EDIT: Tôi đã tìm ra nó. Tôi đã liên kết với biểu mẫu đăng nhập bằng cách chuyển trang hiện tại dưới dạng tham số GET và sau đó sử dụng 'next' để chuyển hướng đến trang đó. Cảm ơn!

EDIT 2: Giải thích của tôi dường như không rõ ràng vì vậy được yêu cầu ở đây là mã của tôi: Hãy nói rằng chúng tôi đang ở trên một trang foo.html và chúng tôi không đăng nhập. Bây giờ chúng tôi muốn có một liên kết trên foo.html liên kết đó để đăng nhập.html. Ở đó chúng tôi có thể đăng nhập và sau đó được chuyển hướng trở lại foo.html. Liên kết trên foo.html trông như thế này:

      <a href='/login/?next={{ request.path }}'>Login</a> 

Bây giờ tôi đã viết một chế độ xem đăng nhập tùy chỉnh trông giống như thế này:

def login_view(request):
   redirect_to = request.REQUEST.get('next', '')
   if request.method=='POST':
      #create login form...
      if valid login credentials have been entered:
         return HttpResponseRedirect(redirect_to)  
   #...
   return render_to_response('login.html', locals())

Và dòng quan trọng trong login.html:

<form method="post" action="./?next={{ redirect_to }}">

Vì vậy, đó là khá nhiều nó, hy vọng rằng làm cho nó rõ ràng.


1
Tôi nghĩ rằng công cụ đăng nhập Django xử lý việc đó cho bạn, nó không hoạt động cho bạn?
Dominic Rodger

Câu trả lời:


151

Bạn không cần phải thực hiện một cái nhìn bổ sung cho điều này, chức năng đã được tích hợp sẵn.

Đầu tiên mỗi trang có liên kết đăng nhập cần biết đường dẫn hiện tại và cách dễ nhất là thêm trình điều khiển ngữ cảnh yêu cầu vào settings.py (4 đầu tiên là mặc định), sau đó đối tượng yêu cầu sẽ có sẵn trong mỗi yêu cầu:

cài đặt:

TEMPLATE_CONTEXT_PROCESSORS = (
    "django.core.context_processors.auth",
    "django.core.context_processors.debug",
    "django.core.context_processors.i18n",
    "django.core.context_processors.media",
    "django.core.context_processors.request",
)

Sau đó thêm vào mẫu bạn muốn liên kết Đăng nhập:

cơ sở.html:

<a href="{% url django.contrib.auth.views.login %}?next={{request.path}}">Login</a>

Điều này sẽ thêm một đối số GET vào trang đăng nhập trỏ về trang hiện tại.

Mẫu đăng nhập sau đó có thể đơn giản như sau:

đăng ký / login.html:

{% block content %}
<form method="post" action="">
  {{form.as_p}}
<input type="submit" value="Login">
</form>
{% endblock %}

47
Cá nhân tôi sử dụng giải pháp này, nhưng một sửa đổi tôi sẽ thực hiện là nó không thành công nếu không request.pathcó giá trị, vì vậy tôi thực hiện {% firstof request.path '/' %}theo cách đó nếu đường dẫn yêu cầu không khả dụng vì một số lý do người dùng được gửi đến trang chủ.
jorelli

1
Tôi đang cố gắng thực hiện giải pháp của bạn, nhưng khi django.contrib.auth.view.login chuyển hướng (sau khi xác thực thành công), trường hợp của Người dùng không có trong yêu cầu, vì vậy user.is_authenticated () luôn trả về Sai. Có ai giúp đỡ không?
juankysmith

3
Thêm vào đầu @jorelli, bạn có thể sử dụng URL được đặt tên và <a href="{% url auth_login %}?next={% firstof request.path '/' %}">Login</a>thay vào đó.
hobbes3

12
Bạn cũng phải coi chừng nếu người dùng đăng nhập sau khi đăng xuất. Nói cách khác, nextđó sẽ là một cái gì đó giống như /accounts/logout/và sau khi người dùng đăng nhập, anh ta sẽ ngay lập tức được đăng xuất lại lol, và vòng lặp tiếp tục.
hobbes3

2
Tôi thấy rằng điều này chỉ hoạt động khi tôi thêm phần sau vào biểu mẫu đăng nhập trên Django 1.5: <input type = "hidden" name = "next" value = "{{next}}" />
Ellis Percival

28

Đây có thể không phải là "cách thực hành tốt nhất", nhưng tôi đã sử dụng thành công điều này trước đây:

return HttpResponseRedirect(request.META.get('HTTP_REFERER','/'))

10
Điều này có một điểm yếu - một số người dùng / trình duyệt đã tắt tham chiếu
Tomasz Zieliński

4
Cũng có vấn đề trong trường hợp người dùng đến một biểu mẫu, điền thông tin và sau đó gửi. HTTP_REFERER sau đó là URL của trang biểu mẫu chứ không phải URL của trang mà người dùng đến từ đầu tiên.
LaundroMat

25

Để hỗ trợ các url đầy đủ với param / value bạn cần:

?next={{ request.get_full_path|urlencode }}

Thay vì chỉ:

?next={{ request.path }}

Trên thực tế đây không phải là một ý tưởng hay, bạn sẽ tìm thấy chuỗi truy vấn rất dài nếu bạn có quá nhiều lần nhấp
dspjm

14

Xác thực tích hợp của Django hoạt động theo cách bạn muốn.

Các trang đăng nhập của họ bao gồm một nextchuỗi truy vấn là trang để trở về sau khi đăng nhập.

Hãy xem http://docs.djangoproject.com/en/dev/topics/auth/#django.contrib.auth.decorators.login_Vquired


4
Chà, trình trang trí login_Vquired sẽ hoạt động tốt khi nó đặt 'tiếp theo' cho bất kỳ trang nào tôi đến, nhưng khi sử dụng trình ẩn danh người dùng trang trí không thể xem trang web vì họ sẽ chuyển hướng đến biểu mẫu đăng nhập ngay lập tức. Tôi nghĩ rằng tôi chỉ cần tìm ra cách đặt giá trị 'tiếp theo' cho url của trang mà người dùng đến từ đó.
jorg

1

Tôi đã liên kết với biểu mẫu đăng nhập bằng cách chuyển trang hiện tại dưới dạng tham số GET và sau đó sử dụng 'next' để chuyển hướng đến trang đó. Cảm ơn!


1

Tôi gặp phải vấn đề tương tự. Giải pháp này cho phép tôi tiếp tục sử dụng chế độ xem đăng nhập chung:

urlpatterns += patterns('django.views.generic.simple',
    (r'^accounts/profile/$', 'redirect_to', {'url': 'generic_account_url'}),
)

1

Trong registration/login.html(lồng trong templatesthư mục) nếu bạn chèn dòng sau, trang sẽ hiển thị như trang đăng nhập quản trị ban đầu của Django:

{% include "admin/login.html" %}

Lưu ý: Tệp chỉ nên chứa các dòng trên.


-1

Xem tài liệu django để xem.login () , bạn cung cấp giá trị 'tiếp theo' (dưới dạng trường ẩn) trên biểu mẫu nhập để chuyển hướng đến sau khi đăng nhập thành công.


Có nhưng làm thế nào để tôi thực sự đặt 'tiếp theo' cho trang tôi đến?
jorg

-3

Bạn cũng có thể làm điều này

<input type="hidden" name="text" value="{% url 'dashboard' %}" />

Câu trả lời sai, nhưng tên = 'tiếp theo' có vẻ khả thi, không được kiểm tra.
WeizhongTu
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.