django自關聯,auth模塊

1、自關聯

寫蠻好的一篇博客:https://www.cnblogs.com/Kingfan1993/p/9936541.html

1.一對多關聯

1.表內自關聯是指表內數據相關聯的對象和表是相同字段,這樣咱們就直接用表內關聯將外鍵關聯設置成自身表的字段html

2.例如,對於微博評論,每條評論均可能有子評論,但每條評論的字段內容應該都是相同的,而且每條評論都只有一個父評論,這就知足了一對多的情形,父評論id爲關聯字段,能夠對應多個子評論python

3.外鍵關聯是在子評論中,有關聯字段的是子評論,子評論查父評論是正向,父評論查子評論是反向web

4.一對多的自關聯能夠應用在BBS論壇的留言功能中數據庫

# models.py中

# 文章表 
"""
id     title         content
1       'hello'      'nihao....'
2       'world'      'shijie....'
"""
class Article(models.Model):
    title = models.CharField(max_length=32)
    content = models.CharField(max_length=500)

# 評論表
"""
id  article_id  content   reply_id(自關聯,做爲外鍵關聯自身表的主鍵id)     uid
1   1           'cool'    0  (不是任何評論的回覆)                      
2   1           'hehe'    0
3   1           'wtf'     1  (表示的是這條評論是回覆id爲1的評論)
4   1           'how'     0
5   2           'haha'    0
6   1           'wow'     1  (也是回覆的第一條評論)
7   2           'Um'      5  (回覆第五條評論)
8   1           'aha'     3  (回覆第三條評論)
"""
class Comment(models.Model):
    article = models.ForeignKey("Article")
    content = models.CharField(max_length=255)
    reply = models.ForeignKey("Comment", default=0)

2.多對多關聯

1.例如,創建一張相親對象表,裏面有男有女,咱們就能夠經過自關聯來創建多對多的關係django

2.經過ManyToManyField將外鍵關聯自身的主鍵idcookie

# models.py中

class User(models.Model):
    name = models.CharField(max_length=32)
    gender_list = [
        (1, "男"),
        (2, "女"),
    ]
    gender = models.IntegerField(choices=gender_list,default=1)
    r = models.ManyToManyField("User")

3.經過python3 manage.py makemigrationspython3 manage.py migrate提交建表模型以後,會生成兩個表,一個是主表,另外一個是從表session

app_user表 和 app_user_r表

4.從表中的的兩個字段,一個是 from_主表名_id,一個是 to_主表名_idapp

5.當咱們經過 from_主表名_id 相關聯的對象查與 to_主表名_id相關聯的對象時,能夠直接經過 '主表對象.關係表(從表)' 查詢函數

# views.py中

# 查詢和jojo的女生
res = models.User.objects.filter(name='jojo', gender=1).first()
#print(res)  # object
objs = res.m.all()  
for obj in objs:
    print(obj.name)
'''
對應的SQL語句:
1. select * from app01_user_m where from_user_id = 1;  
獲得的結果就是對應到app_user_r表中的數據時:to_user_id=[3,4] 所對應的對象

2. select * from app01_user where id in (3,4);
'''

6.當咱們 經過 to_主表名_id相關聯的對象查 from_主表名_id 相關聯的對象時,則須要經過 '主表對象.關係表_set' 進行查詢ui

# views.py中

# 查詢和 fanbingbing 約會的男生
res = models.User.objects.filter(name='fanbingbing', gender=2).first()
objs = res.user_set.all()
for obj in objs:
    print(obj.name)
'''
對應的SQL語句:
1. select * from app01_user_m where to_user_id = 3; 
獲得的結果就是對應到app_user_r表中的數據時:from_user_id=[1,2] 所對應的對象

2. select * from app01_user where id in (1,2); 
'''

2、auth模塊

1.auth的簡單使用

1.執行數據庫遷移的那兩條命令時,即便咱們沒有建表,django是否是也會建立好多張表?咱們建立以後去看一下里面的一個叫auth_user表,既然是表,那確定應該有對應的操做改表的方法

2.auth_user表的記錄的添加:建立超級用戶,不能夠手動插入,由於密碼是加密的,手動添加的明文密碼沒有意義

3.咱們能夠在pycharm中使用導航欄中的Tools裏的run manage.py Task 中輸入createsuperuser

# views.py 中

# 就可使用auth認證了,作一個簡單的登錄

from django.contrib import auth

def test(request):

    if request.method == "GET":
        return render(request,"test.html")
    else:
        name = request.POST.get("user")
        psw = request.POST.get("psw")

        myuser = auth.authenticate(request,username=name,password=psw)  # 若是auth_user表中有這條記錄,則返回一個user對象(通常就是用戶名)

        if myuser: 

            auth.login(request,myuser)  # 會產生一個user對象,能夠在任何視圖函數中調用
            """
            給當前成功登錄的用戶保存登錄狀態,以前是經過cookie或者session,如今經過auth;
            request.session["name"] = name等價於:auth.login(request,myuser)
            """
            
            return HttpResponse("success")
        else:
            return redirect("/test/")

# 在其餘視圖函數中演示
def other(request):
    
    print(request.user)
    print(request.user.is_authenticated)
    
    return HttpResponse("ok")
# 總結:
# 1.只要登錄成功執行了auth.login(request,user)
# 以後在其餘任意的視圖函數中均可以經過request.user獲取當前登錄用戶對象

# 2.當沒有執行auth.login,request.user打印出來的是匿名用戶。將session表數據刪除便可演示該效果

# 3.如何判斷request.user用戶是否經過auth.login登錄呢?request.user.is_authenticated,打印:print(request.user.is_authenticated)

# 爲什麼執行auth.login以後,其餘視圖函數中就能夠經過request.user拿到當前登錄對象呢?
# django的中間件中有沒有一個叫 'django.contrib.auth.middleware.AuthenticationMiddleware'的中間件,它幹了件什麼事,能不能推導一下?
# 在web端取出session去django_session表裏面查相應的數據

4.註銷

auth.logout(request)
# 等價於刪除session數據request.session.flush()

2.裝飾器

# 裝飾器校驗是否登錄及跳轉

from django.contrib.auth.decorators import login_required

@login_required(login_url='/login/',redirect_field_name='old')  # 沒登錄會跳轉到login頁面,而且後面會拼接上你上一次想訪問的頁面路徑/login/?old=/my_view/,能夠經過redirect_field_name參數修改next鍵名(若是不寫這個參數,則爲127.0.0.1:8090/login/?old=/my_view/,再無啥用了)
def my_view(request):
  return HttpResponse("ok")

若是我全部的視圖函數都須要裝飾並跳轉到login頁面,那麼會很繁瑣,咱們能夠在項目下的settings.py文件中進行配置

# settings.py

# 能夠在配置文件中指定auth校驗登錄不合法統一跳轉到某個路徑
LOGIN_URL = '/login/'  # 既能夠全局配置,也能夠局部配置

3.經過auth實現註冊功能

1.咱們除了經過命令行輸入,還能夠經過auth提供的其餘方法,對auth_user表進行數據的添加

# app的views.py文件中

from django.contrib.auth.models import User

def register(request):
    if request.method == "GET":
        return render(request, "register.html")
    else:
        user_name = request.POST.get("username")
        psw = request.POST.get("psw")
        
        # User.objects.create()  # 不能用這個,由於密碼是明文

        User.objects.create_user(username=user_name,password=psw)  # 建立普通用戶
        # User.objects.create_superuser(username=user_name,password=psw,email=233@qq.com)  # 建立超級用戶

4.修改密碼

def modify(request):
    if request.method=='GET':
        return render(request, 'modify.html')
    else:
        oldpsw = request.POST.get('oldpsw')
        newpsw = request.POST.get('newpsw')

        res = request.user.check_password(oldpsw) # 獲取密碼
        print(res)
        if res:
            request.user.set_password(newpsw)
            request.user.save()
            return HttpResponse('ok')
        else:
            return render(request, 'modify.html')

5.自定義模型表應用auth功能

1.擴張auth_user表

2.一對一關聯(不推薦)

from django.contrib.auth.model s import User

class UserDetail(models.Models):
    phone_number = models.CharField(max_length=11)
    user = models.OnoToOneField(to=User)

3.面向對象的繼承

  • 須要在項目下的settings.py文件中進行配置
# settings.py中

"""
1.指定我再也不使用默認的auth_user表而是使用我本身建立的Userinfo表
2.自定義認證系統默認使用的數據表以後,咱們就能夠像使用默認的auth_user表那樣使用咱們的UserInfo表了
3.庫裏面也沒有auth_user表了,原來auth表的操做方法,如今所有用自定義的表都可實現
"""

# AUTH_USER_MODEL = "app名.models裏面對應的模型表名"
AUTH_USER_MODEL = "app01.User"
  • 就能夠在app下的models.py文件中建立咱們本身的用戶信息表了
# models.py中

from django.contrib.auth.models import User,AbstractUser

# 繼承了auth中的user表
class UserInfo(AbstractUser):
    phone_number = models.CharField(max_length=32)

6.總結

1.auth登陸
            
            obj = auth.authenticate(username, password)
            
            if obj:
                auth.login(request, obj)
                
        2.業務邏輯函數驗證:
            
            - request.user.is_authenticated()
            
            - from django.contrib.auth.decorators import login_required
                @login_required()
            
        3.auth註冊:
            本質就是向auth_user表添加數據
            
            - createsuperuser
            
            - models.User.objects.create_user()   
            - models.User.objects.create_superuser()   
            
        4.auth的密碼更該:
            
            auth.checkpassword()  : 驗證原來的密碼是否正確
            
            auth.setpassword() : 設置新的密碼
            
            auth.save()
            
        5.註銷(登出)
            
            auth.logout(request)
            
            本質上就是刪除django_session中所對應的的記錄
            
        6.auth_user表的擴展:
            
            - onetoonefield
            
            - 繼承子 AbstractUser 類
相關文章
相關標籤/搜索