一對一外鍵
若是你對用戶驗證方法authenticate沒有更多的要求,就是使用username和password就能夠完成用戶的登陸驗證工做,可是想要在原來的模型的基礎上添加新的字段,那麼就能夠使用一對一外鍵的方式,定義一個用戶的擴展模型,示例代碼以下:
from django.contrib.auth.models import User
from django.db import models
from django.core import validators
from django.dispatch import receiver
import djang.db.models.signals import post_save
class UserExtension(models.Model):
<!--一對一的指定外鍵,若是使用foreignkey的外鍵形式進行引用,就會使表與表之間的關係並非一對一的,有多是多對多的,這樣的話,在處理的時候就不太方便-->
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='extension')
telephone = models.CharField(max_length=11, validators=[validators.RegexValidator(r"1[345678]\d{9}"")])
school = models.CharField(max_length=100)
<!--定義一個信號,用於監聽User模型是否使用了save()方法-->
@receiver(post_save, sender=User)
def handler_user_extension(sender, instance, created, **kwargs):
if created:
# UserExtension02的user必須是User的instance
# 不能是UserExtension02.objects.create(user=User)
UserExtension.objects.create(user=instance)
else:
# Manager isn't accessible via User instances 在views.py文件中爲user.extension.telephone字段添加值時出現該錯誤:
# 緣由就是將instance.extension.save()錯誤的寫成instance.extension.save()
instance.extension.save()
須要注意的是,必定要將新建立的模型映射到數據庫中。
(1)在views.py文件中爲新建立的user擴展表添加一條數據,示例代碼以下:
from django.shortcuts import render
from django.http import HttpResponse
from django.contrib.auth.models import User
from .models import UserExtension
<!--1. 添加一條數據-->
def one_to_one(request):
user = User.objects.create_user(username='孤煙逐雲', email='111111@qq.com', password='111111')
user.extension.telephone = '18833332222'
user.save()
return render(request, 'one_to_one.html')
(2)自定義登陸的驗證函數,採用擴展模型中的telephone和password字段驗證。示例代碼以下:
def my_authenticate(telephone, password):
user = User.objects.filter(extension__telephone=telephone).first()
if user:
<!--若是該手機號的用戶存在,再判斷輸入的密碼是否正確-->
is_true = user.check_password(password)
if is_true:
return user
print('您查找的用戶是:%s' % user.username)
else:
return None
else:
return None
(3)調用定義好的登陸驗證函數,進行用戶的驗證,示例代碼以下:
def one_to_one(request):
telephone = request.GET.get('telephone')
password = request.GET.get('password')
user = my_authenticate(telephone, password)
if user:
print('您查找的用戶是:%s' % user.username)
context = {
'user': user
}
return render(request, 'one_to_one.html', context=context)
else:
context = {
'user': '您查找的用戶不存在!'
}
return render(request, 'one_to_one.html', context=context)
在one_to_one.html中接收視圖函數傳遞的上下文,示例代碼以下:
<ul>
<li>用戶名:{{ user.username }}</li>
<li>手機號{{ user.extension.telephone }}</li>
</ul>