Day6-課堂筆記-Django6

1.自定義登錄

1)創(chuàng)建user表

user->models.py

class Users(models.Model):
    username=models.CharField(max_length=10,unique=True,verbose_name='用戶名')
    password=models.CharField(max_length=255,verbose_name='密碼')
    create_time=models.DateTimeField(auto_now_add=True,verbose_name='創(chuàng)建時(shí)間')
    operate_time=models.DateTimeField(auto_now=True,verbose_name='修改時(shí)間')

    class Meta:
        db_table='users'

2)用戶注冊代碼

def register(request):
    if request.method=='GET':
        # 如果請求為get蔽豺,返回注冊頁面
        return render(request,'register.html')
    if request.method=='POST':
        #校驗(yàn)參數(shù)
        form=UserForm(request.POST)
        # 判斷是否校驗(yàn)成功呆瞻,is_valid()為true校驗(yàn)成功
        if form.is_valid():
            # 注冊,使用make_password進(jìn)行密碼加密,否則為明文
            password=make_password(form.cleaned_data['password1'])
            Users.objects.create(username=form.cleaned_data['username'],
                                 password=password)
            # 跳轉(zhuǎn)到登錄頁面彤侍,使用namespace:name
            return HttpResponseRedirect(reverse('user:login'))
        else:
            return render(request,'register.html',{'form':form})

2.設(shè)置裝飾器

1)創(chuàng)建user_ticket表

class UserTicket(models.Model):
    #
    user=models.ForeignKey(Users)
    ticket=models.CharField(max_length=30)
    create_time=models.DateTimeField(auto_now_add=True,verbose_name='創(chuàng)建時(shí)間')
    max_age=models.DateTimeField(auto_now=True,verbose_name='修改時(shí)間')
    class Meta:
        db_table='user_ticket'

2)登錄:

def login(request):
    if request.method=='GET':
        return render(request,'login.html')
    if request.method=='POST':
        # 校驗(yàn)登錄頁面?zhèn)鬟f的參數(shù)
        form=LoginForm(request.POST)
        # 使用is_valid()判斷是否校驗(yàn)成功
        if form.is_valid():
            # 登錄的設(shè)置
            # 1.通過用戶名和密碼獲取當(dāng)前的user對(duì)象-->類似authenticate
            user=Users.objects.filter(username=form.cleaned_data['username']).first()
            if user:
                # 可以通過username獲取到對(duì)象
                # 將user.password和from.form.cleaned_data['password']進(jìn)行校驗(yàn)
                if check_password(form.cleaned_data['password'],user.password):
                    # 校驗(yàn)用戶名和密碼都成功
                    #1.向cookie中設(shè)置隨機(jī)參數(shù)ticket
                    res = HttpResponseRedirect(reverse('user:index'))
                    ticket=get_ticekt()
                    # set_cookie(key,value,max_age'',expires=''),key鍵谤民,value值败富,max_age存活時(shí)間-s,expires-天
                    # 設(shè)置cookie中的隨機(jī)值-->類似auth.login
                    res.set_cookie('ticket',ticket,max_age=100)
                    # 刪除cookie,delete_cookie(key)
                    # delete_cookie('ticket')
                    # 2.在表user_ticket中設(shè)置這個(gè)ticket和user的對(duì)象關(guān)系
                    # 設(shè)置user_ticket中ticket的隨機(jī)值
                    UserTicket.objects.create(user=user,ticket=ticket)
                    return res
                else:
                    # 密碼錯(cuò)誤
                    return render(request,'login.html',{'password':'密碼錯(cuò)誤'})
            else:
                # 登錄系統(tǒng)的用戶不存在
                return render(request,'login.html',{'username':'用戶不存在'})
            pass
        else:
            return render(request,'login.html',{'form':form})

3)登錄跳轉(zhuǎn)首頁驗(yàn)證(裝飾器)

方法一:
得到隨機(jī)ticket
utils->functions->get_ticekt

def get_ticekt():
    s='1234567890qwertyuiopasdfghjklzxcvbnm'
    ticket=''
    for i in range(25):
        ticket+=random.choice(s)
    return ticket

user->views

def index(request):
    if request.method=='GET':
        # 從cookie中拿ticket
        ticket=request.COOKIES.get('ticket')
        user_ticket=UserTicket.objects.filter(ticket=ticket).first()
        if user_ticket:
            #獲取當(dāng)前登錄系統(tǒng)的用戶
            user=user_ticket.user
            return render(request,'index.html',{'user':user})
        else:
            return HttpResponseRedirect(reverse('user:login'))
        

方法二:
創(chuàng)建裝飾器:

# func是一個(gè)函數(shù)绸狐,該函數(shù)是在裝飾器下面的函數(shù)
def is_login(func):
    def check(request):
        ticket=request.COOKIES.get('ticket')
        # 如果cookie中存在設(shè)置的ticket則通過user_ticket表進(jìn)行校驗(yàn)
        if ticket:
            user_ticket=UserTicket.objects.filter(ticket=ticket).first()
            if user_ticket:
                return func(request)
            else:
                # ticket參數(shù)錯(cuò)誤卤恳,則跳轉(zhuǎn)到登錄
                return HttpResponseRedirect(reverse('user:login'))
        else:
            # 沒有登錄
            return HttpResponseRedirect(reverse('user:login'))
    return check

方法三:
djg6->settings->MIDDLEWARE:末尾添加

'utils.UserAuthMiddleWare.UserMiddleware',

utils中創(chuàng)建UserAuthMiddleWare.py

from datetime import datetime

from django.http import HttpResponseRedirect
from django.urls import reverse
from django.utils.deprecation import MiddlewareMixin

from user.models import UserTicket


class UserMiddleware(MiddlewareMixin):
    # 重構(gòu)攔截請求的方法
    def process_request(self,request):
        # 排除不需要登錄驗(yàn)證的地址
        not_login_path=['/user/login/','/user/register/']
        path=request.path
        # 校驗(yàn)不需要登錄驗(yàn)證的地址
        for n_path in not_login_path:
            # 如果當(dāng)前訪問的地址是登錄或注冊地址累盗,則直接訪問對(duì)應(yīng)的視圖函數(shù)
            if path==n_path:
                return None
        # ticket=request.COOKIES.get('ticket')
        ticket=request.COOKIES.get('ticket')
        # 如果請求的cookie中沒有ticket,則跳轉(zhuǎn)到登錄
        if not ticket:
            return HttpResponseRedirect(reverse('user:login'))

        # 刪除user_ticket表中,時(shí)間超過了1000s的記錄
        user_tickets = UserTicket.objects.all()
        user_tickets.update(max_age=datetime.now())
        for user in user_tickets:
            times = datetime.timestamp(user.create_time) + 1000000 - datetime.timestamp(user.max_age)
            if times < 0:
                user.delete()

        # 如果請求的user_ticket中沒有與cookie中相等的ticket,則跳轉(zhuǎn)到登錄
        user_ticket=UserTicket.objects.filter(ticket=ticket).first()
        if not user_ticket:
            return HttpResponseRedirect(reverse('user:login'))
        # 設(shè)置全局的user
        request.user=user_ticket.user
        # 返回中間件執(zhí)行結(jié)束突琳,可返回None或可不寫
        return None

4)刪除ticket

utils->UserAuthMiddleWare.py

# 刪除user_ticket表中若债,時(shí)間超過了1000s的記錄
        user_tickets = UserTicket.objects.all()
        user_tickets.update(max_age=datetime.now())
        for user in user_tickets:
            times = datetime.timestamp(user.create_time) +8*60*60+100 - datetime.timestamp(user.max_age)
            if times < 0:
                user.delete()

5)注銷

方法一:
views

def logout(request):
    if request.method=='GET':
        # 注銷寫法
        ticket=request.COOKIES.get('ticket')
        user_ticket=UserTicket.objects.filter(ticket=ticket).first()
        if user_ticket:
            user_ticket.delete()
        return HttpResponseRedirect(reverse('user:login'))

方法二:
utils->functions.py->is_logout:

def is_logout(func):
    def check(request):
        ticket = request.COOKIES.get('ticket')
        if ticket:
            user_ticket = UserTicket.objects.filter(ticket=ticket).first()
            if user_ticket:
                user_ticket.delete()
                return func(request)
            else:
                return HttpResponseRedirect(reverse('user:login'))
        else:
            return HttpResponseRedirect(reverse('user:login'))
    return check
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市拆融,隨后出現(xiàn)的幾起案子蠢琳,更是在濱河造成了極大的恐慌啊终,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,188評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件傲须,死亡現(xiàn)場離奇詭異蓝牲,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)泰讽,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門例衍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人已卸,你說我怎么就攤上這事佛玄。” “怎么了累澡?”我有些...
    開封第一講書人閱讀 165,562評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵梦抢,是天一觀的道長。 經(jīng)常有香客問我愧哟,道長奥吩,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,893評(píng)論 1 295
  • 正文 為了忘掉前任蕊梧,我火速辦了婚禮圈驼,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘望几。我一直安慰自己绩脆,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,917評(píng)論 6 392
  • 文/花漫 我一把揭開白布橄抹。 她就那樣靜靜地躺著靴迫,像睡著了一般。 火紅的嫁衣襯著肌膚如雪楼誓。 梳的紋絲不亂的頭發(fā)上玉锌,一...
    開封第一講書人閱讀 51,708評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音疟羹,去河邊找鬼主守。 笑死,一個(gè)胖子當(dāng)著我的面吹牛榄融,可吹牛的內(nèi)容都是我干的参淫。 我是一名探鬼主播,決...
    沈念sama閱讀 40,430評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼愧杯,長吁一口氣:“原來是場噩夢啊……” “哼涎才!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起力九,我...
    開封第一講書人閱讀 39,342評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤耍铜,失蹤者是張志新(化名)和其女友劉穎邑闺,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體棕兼,經(jīng)...
    沈念sama閱讀 45,801評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡陡舅,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,976評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了伴挚。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蹭沛。...
    茶點(diǎn)故事閱讀 40,115評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖章鲤,靈堂內(nèi)的尸體忽然破棺而出摊灭,到底是詐尸還是另有隱情,我是刑警寧澤败徊,帶...
    沈念sama閱讀 35,804評(píng)論 5 346
  • 正文 年R本政府宣布帚呼,位于F島的核電站,受9級(jí)特大地震影響皱蹦,放射性物質(zhì)發(fā)生泄漏煤杀。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,458評(píng)論 3 331
  • 文/蒙蒙 一沪哺、第九天 我趴在偏房一處隱蔽的房頂上張望沈自。 院中可真熱鬧,春花似錦辜妓、人聲如沸枯途。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽酪夷。三九已至,卻和暖如春孽惰,著一層夾襖步出監(jiān)牢的瞬間晚岭,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評(píng)論 1 272
  • 我被黑心中介騙來泰國打工勋功, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留坦报,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,365評(píng)論 3 373
  • 正文 我出身青樓狂鞋,卻偏偏與公主長得像片择,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子要销,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,055評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 1.有序列表构回、無序列表、自定義列表如何使用疏咐?寫個(gè)簡單的例子纤掸。三者在語義上有什么區(qū)別?在哪些情況下使用哪種(重要)浑塞?...
    浩天天閱讀 259評(píng)論 0 0
  • 1.文件與數(shù)據(jù) Tableau使用的數(shù)據(jù)結(jié)構(gòu)必須是標(biāo)準(zhǔn)的關(guān)系型數(shù)據(jù)庫中的二維表結(jié)構(gòu)借跪。 1.1 Tableau文件類...
    李慕玄閱讀 4,783評(píng)論 1 1
  • 16-01-23 星期六 雨 21天 回來的很及時(shí),晚八點(diǎn)打開手機(jī)酌壕,恰巧遇上弘丹在打卡群分享的二維碼掏愁,點(diǎn)進(jìn)去,樹...
    年念玲閱讀 155評(píng)論 5 1
  • 億高黃金:I can fly,飛得更高 “I can fly糊昙,飛得更高……”是啊億高黃金辛掠!人的一生就是一本奮斗史,...
    2個(gè)小豆豆閱讀 331評(píng)論 0 0