03 用戶登錄的常見模塊和使用

next在登錄頁面的妙用

在用戶的登錄頁面判斷url中是否含有next參數,若是有則跳轉到,登錄前的url:html

經常使用的是在登錄的LoginView處理函數中,把如下的代碼添加和修改局部的登錄函數:python

# 判斷頁面url中是否有next參數,
next = request.GET.get("next")
# 若是有,則跳轉到next的url
if next:
    return redirect(next)
else:
    # 若是沒有,跳轉到主頁
    return redirect(reverse("goods:index"))

  完整代碼:django

class LoginView(View):
    """登陸"""
    def get(self, request):
        """提供登陸頁面"""
        return render(request, "login.html")

    def post(self, request):
        """處理登陸的數據"""
        # 獲取參數
        user_name = request.POST.get("username")
        password = request.POST.get("pwd")
        remembered = request.POST.get("remembered")  # 記住用戶名的參數

        # 參數校驗
        if not all([user_name, password]):
            # 參數不完整
            return render(request, "login.html")

        # 登陸業務邏輯處理
        # try:
        #     password = sha256(password)
        #     User.objects.get(username=user_name, password=password)
        # except User.DoesNotExist:
        #     return HttpResponse("用戶名或密碼錯誤")

        # 使用django的認證系統進行用戶密碼的校驗
        user = authenticate(username=user_name, password=password)
        if user is None:
            # 用戶的登陸信息有誤
            return render(request, "login.html", {"errmsg": "用戶名或密碼錯誤!"})

        # 判斷用戶的激活狀態
        if user.is_active is False:
            return render(request, "login.html", {"errmsg": "用戶還沒有激活!"})

        # 保存用戶的登陸狀態
        # 使用django的login函數保存用戶的session數據
        login(request, user)
        # 根據用戶勾選的記住用戶名選項,設置session數據的有效期(django幫助咱們完成cookie有效期的設置)
        if remembered != "on":
            # 表示用戶沒有勾選
            request.session.set_expiry(0)  # 設置爲臨時會話
        else:
            # 表示用戶勾選
            request.session.set_expiry(None)  # 採用django的默認設置有效期

        # 登陸成功,
        # 判斷頁面url中是否有next參數,
        next = request.GET.get("next")
        # 若是有,則跳轉到next的url
        if next:
            return redirect(next)
        else:
            # 若是沒有,跳轉到主頁
            return redirect(reverse("goods:index"))
View Code

在下面的頁面中的url改成:安全

  

http://127.0.0.1:8000/users/login

  用戶就跳轉到了登錄的頁面:cookie

在用戶輸入完,用戶和密碼後會跳轉到原來的網頁:session

 

 ====================================================================================================================ide

如何退出一個用戶

 若要退出一個已經經過django.contrib.auth.login()登入的用戶,能夠在你的視圖中使用django.contrib.auth.logout() 它接收一個HttpRequest對象且沒有返回值函數

定義退出是請求的處理函數:post

from django.contrib.auth import authenticate, login, logout

class LogoutView(View):
    """退出"""
    def get(self, request):
        # 使用django的認證系統提供的logout函數,清除session數據
        logout(request)
        # 跳轉到主頁
        return redirect(reverse("goods:index"))

 

定義退出的請求路徑:ui

url(r'^logout$', views.LogoutView.as_view(), name="logout"),

在任一個登錄過的頁面都有登錄過的session信息,以下圖:

在上面途中的地址欄中填寫退出登錄的url:

http://127.0.0.1:8000/users/logout

  

session清除掉了,而且重定向到了指定的網頁

=============================================================================================================

只容許登陸的用戶訪問

login_required 裝飾器,login_required([redirect_field_name=REDIRECT_FIELD_NAME, login_url=None])

做爲一個快捷方式,你可使用便捷的login_required()裝飾器:

from django.contrib.auth.decorators import login_required @login_required(redirect_field_name='my_redirect_field') def my_view(request): ...

login_required()完成下面的事情:

  • 若是用戶沒有登入,則重定向到settings.LOGIN_URL,並將當前訪問的絕對路徑傳遞到查詢字符串中。例如:/accounts/login/?next=/polls/3/
  • 若是用戶已經登入,則正常執行視圖。視圖的代碼能夠安全地假設用戶已經登入。

默認狀況下,在成功認證後用戶應該被重定向的路徑存儲在查詢字符串的一個叫作"next"的參數中。若是對該參數你傾向使用一個不一樣的名字,login_required()帶有一個可選的redirect_field_name參數:

Django認證系統文檔:http://python.usyiyi.cn/documents/django_182/topics/auth/default.html

自定義一個給全部只容許登錄過的用戶訪問的基類,在utils包中建立文件views.py

 

 

 由於我用的到時類視圖,因此我重構了as_view方法,用login_required裝飾as_view編寫以下的代碼:,

from django.contrib.auth.decorators import login_required


class LoginRequiredMixin(object):
    """要求用戶登陸的功能補充邏輯"""
    @classmethod
    def as_view(cls, **initkwargs):
        view = super(LoginRequiredMixin, cls).as_view(**initkwargs)   # 實際上就是調用的django提供的類視圖基類的as_view
        return login_required(view)

 

 定義地址信息的請求處理函數,而且只有登錄過的用戶才能夠訪問,導入自定義的限制訪問的基類 from utils.views import LoginRequiredMixin

 

from utils.views import LoginRequiredMixin

class AddressView(LoginRequiredMixin, View):
    """用戶地址"""
        return render(request, "user_center_site.html", context)

在應用users中添加地址信息的url

    url(r'^address$', views.AddressView.as_view(), name="address"),

 在配置文件中,用戶沒有登錄重定向的頁面:

LOGIN_URL = '/users/login'

 沒登錄的用來直接訪問返回到登錄的頁面

http://127.0.0.1:8000/users/address

  

用戶登錄後在地址欄中輸入:

http://127.0.0.1:8000/users/address

  顯示的頁面以下:

在Address中get 方法中給傳用戶的地址信息進行渲染,request請求中包含了用戶的信息,咱們能夠直接調用request.user獲取當前的對象user

經過當前的user表查到最新的地址信息表user.address_set.latest("create_time")

class AddressView(LoginRequiredMixin, View):
    """用戶地址"""
    def get(self, request):
        """提供用戶地址頁面"""
        user = request.user  #登陸的用戶對象

        # 獲取用戶的地址信息,按照建立時間選擇最新的一條
        try:
            address = user.address_set.latest("create_time")
        except Address.DoesNotExist:
            address = None

        context = {
            # "user": user,  # 這個數據能夠不用傳,在的django中能夠直接使用
            "address": address
        }

        # 渲染模板
        return render(request, "user_center_site.html", context)

  

在Address中post方法中讓用戶修改最新的地址信息進行渲染:

    def post(self, request):
        """維護地址信息"""
        user = request.user

        recv_name = request.POST.get("recv_name")
        addr = request.POST.get("addr")
        zip_code = request.POST.get("zip_code")
        recv_mobile = request.POST.get("recv_mobile")

        if all([recv_name, addr, zip_code, recv_mobile]):
            # address = Address(
            #     user=user,
            #     receiver_name=recv_name,
            #     detail_addr=addr,
            #     zip_code=zip_code,
            #     receiver_mobile=recv_mobile
            # )
            # address.save()
            Address.objects.create(
                user=user,
                receiver_name=recv_name,
                detail_addr=addr,
                zip_code=zip_code,
                receiver_mobile=recv_mobile
            )
        return redirect(reverse("users:address"))

隨便填寫提交的返回頁面以下:

相關文章
相關標籤/搜索