溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

Django User 模塊之 AbstractUser 擴(kuò)展詳解

發(fā)布時(shí)間:2020-10-06 08:23:09 來(lái)源:腳本之家 閱讀:222 作者:種子選手 欄目:開(kāi)發(fā)技術(shù)

最近在寫(xiě)博客,剛好寫(xiě)到用戶(hù)注冊(cè)注銷(xiāo)模塊,覺(jué)得這一方面還是挺有趣的。當(dāng)嘗試掀開(kāi) Django 的源代碼時(shí)一切 API 就不會(huì)變得那么摸不著。順著讀Django 的各模塊源碼,我們可以更靈活地更改代碼以實(shí)現(xiàn)自己想要的功能。

現(xiàn)在,思考一個(gè)問(wèn)題,主需求是實(shí)現(xiàn)博客中用戶(hù)的注冊(cè)登錄登出功能。如果只滿足于用戶(hù)注冊(cè)時(shí)只登記其郵箱或是用戶(hù)名,Django 自帶的 User 模塊既可以實(shí)現(xiàn)。但實(shí)際上,一個(gè)普遍的要求是注冊(cè)用戶(hù)應(yīng)該能夠修改自己的頭像信息,郵箱信息,昵稱(chēng)信息等其他更靈活的需求。

可以先看一下 Django User 模塊的源碼

class User(AbstractUser):
  """
  Users within the Django authentication system are represented by this
  model.

  Username, password and email are required. Other fields are optional.
  """
  class Meta(AbstractUser.Meta):
    swappable = 'AUTH_USER_MODEL'

注意:如果你的是 Anaconda 管理,可以在路徑 C:\Users\User\Anaconda3\Lib\site-packages\django\contrib\auth\models.py 查看

Django 中的 User 模塊實(shí)際上繼承了 AbstractUser 模塊,AbstractUser 模塊下有 :

username
first_name
last_name
email
date_joined

你可以看出,User 模塊繼承了 AbstractUser 抽象基類(lèi),而僅僅只是繼承了,并沒(méi)有對(duì) AbstractUser 進(jìn)行任何擴(kuò)展。所以,對(duì)于一個(gè)需要更多需求的 User 模塊信息來(lái)說(shuō),我們可以繼承 AbstractUser 并根據(jù)自己的需求進(jìn)行擴(kuò)展。

現(xiàn)在,我們對(duì)用戶(hù)屬性添加一些需求,比如支持用戶(hù)修改頭像、支持用戶(hù)昵稱(chēng)、qq、wechat 以及網(wǎng)站鏈接等。

class User(AbstractUser):
  nickname = models.CharField(max_length=30, blank=True, null=True, verbose_name='昵稱(chēng)')
  qq = models.CharField(max_length=20, blank=True, null=True, verbose_name='QQ號(hào)碼')
  url = models.URLField(max_length=100, blank=True, null=True, verbose_name='個(gè)人網(wǎng)頁(yè)地址')
  avatar = ProcessedImageField(upload_to='avatar',
default='avatar/default.png', verbose_name='頭像')

  class Meta:
    verbose_name = '用戶(hù)'
    verbose_name_plural = verbose_name
    ordering = ['-id']

  def __str__(self):
    return self.username

我們給自定義的用戶(hù)模塊增加 nickname(昵稱(chēng)), qq, url(網(wǎng)站鏈接),avatar(頭像)屬性。

注意:為了讓 Django 能夠識(shí)別使用自定義的用戶(hù)模型,必須要在 settings.py 中設(shè)置自定義模塊位置,如在 settings.py 上添加

AUTH_USER_MODEL = 'blog.user'

其中,blog 為你對(duì)應(yīng)的應(yīng)用 app 信息,user 為 blog 應(yīng)用下的 user 模塊,在這里 blog 和 user 大小寫(xiě)無(wú)關(guān)。

如果在你現(xiàn)在執(zhí)行數(shù)據(jù)庫(kù)遷移命令,可能會(huì)出現(xiàn) blog 不存在 user 模塊 的提示,而無(wú)法重新進(jìn)行數(shù)據(jù)遷移。

ValueError: The field account.EmailAddress.user was declared with a lazy reference to 'blog.user', but app 'blog' doesn't provide model 'user'.
The field admin.LogEntry.user was declared with a lazy reference to 'blog.user', but app 'blog' doesn't provide model 'user'.
The field blog.Article.author was declared with a lazy reference to 'blog.user', but app 'blog' doesn't provide model 'user'.
The field easy_comment.Comment.user was declared with a lazy reference to 'blog.user', but app 'blog' doesn't provide model 'user'.
The field easy_comment.Like.user was declared with a lazy reference to 'blog.user', but app 'blog' doesn't provide model 'user'.
The field notifications.Notification.recipient was declared with a lazy reference to 'blog.user', but app 'blog' doesn't provide model 'user'.
The field online_status.OnlineStatus.user was declared with a lazy reference to 'blog.user', but app 'blog' doesn't provide model 'user'.
The field socialaccount.SocialAccount.user was declared with a lazy reference to 'blog.user', but app 'blog' doesn't provide model 'user'.

所以,如果之前是使用例如 AUTH_USER_MODEL = auth.user 的用戶(hù)模型,并重新將其自定義為 AUTH_USER_MODEL = blog.user 請(qǐng)刪掉 migrations 目錄下的所有文件 以及數(shù)據(jù)庫(kù)文件。

刪除之后,重新進(jìn)行數(shù)據(jù)庫(kù)的遷移

$ python manage.py makemigrations myapp
$ python manage.py migrate

這個(gè)時(shí)候,所使用的用戶(hù)即為自定義后的用戶(hù)了。

 File "C:\Users\Micky\Anaconda3\lib\site-packages\django\db\backends\utils.py", line 85, in _execute
  return self.cursor.execute(sql, params)
 File "C:\Users\Micky\Anaconda3\lib\site-packages\django\db\backends\sqlite3\base.py", line 303, in execute
  return Database.Cursor.execute(self, query, params)
django.db.utils.OperationalError: no such table: blog_user

這里可以在模板中指定數(shù)據(jù)庫(kù) db_table = 'user'

補(bǔ)充知識(shí):Django學(xué)習(xí)筆記——內(nèi)置用戶(hù)類(lèi)AbstractUser與內(nèi)置認(rèn)證校驗(yàn)系統(tǒng)

內(nèi)置用戶(hù)類(lèi)AbstractUser

我們?cè)谥爸v過(guò)了model模型的作用和父類(lèi)的作用,這次介紹的內(nèi)置用戶(hù)類(lèi)AbstractUser就是Django內(nèi)置的一個(gè)關(guān)于用戶(hù)操作的類(lèi),它極大地方便了我們對(duì)model模型中對(duì)User用戶(hù)類(lèi)的設(shè)計(jì)。而所謂內(nèi)置用戶(hù)類(lèi)的本質(zhì)也就是一個(gè)封裝好的父類(lèi),所以使用起來(lái)是相當(dāng)?shù)姆奖恪?/p>

#導(dǎo)入AbstractUser類(lèi)
from django.contrib.auth.models import AbstractUser

#直接繼承就可以了,如果有需要就向?qū)こodel一樣寫(xiě)字段就可以
class User(AbstractUser):
  pass

我們通過(guò)查看AbstractUser的源碼可以知道它設(shè)有幾個(gè)字段

#用戶(hù)名
username = models.CharField(
    _('username'),
    max_length=150,
    unique=True,
    help_text=_('Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.'),
    validators=[username_validator],
    error_messages={
      'unique': _("A user with that username already exists."),
    },
  )
  
  #名
  first_name = models.CharField(_('first name'), max_length=30, blank=True)
  
  #姓
  last_name = models.CharField(_('last name'), max_length=150, blank=True)
  
  #郵箱
  email = models.EmailField(_('email address'), blank=True)
  
  #權(quán)限
  is_staff = models.BooleanField(
    _('staff status'),
    default=False,
    help_text=_('Designates whether the user can log into this admin site.'),
  )
  
  #激活
  is_active = models.BooleanField(
    _('active'),
    default=True,
    help_text=_(
      'Designates whether this user should be treated as active. '
      'Unselect this instead of deleting accounts.'
    ),
  )
  
  #日期
  date_joined = models.DateTimeField(_('date joined'), default=timezone.now)

內(nèi)置認(rèn)證校驗(yàn)系統(tǒng)

django自帶的用戶(hù)認(rèn)證校驗(yàn)系統(tǒng)較為簡(jiǎn)單,主要就是認(rèn)證用戶(hù)名密碼的正確與否

首先要在settings里面配置

#使用自帶的認(rèn)證系統(tǒng)
AUTH_USER_MODEL = "user.User"

這是配合自帶的用戶(hù)類(lèi)AbstractUser一起使用的

通常使用在類(lèi)視圖中的post方法校驗(yàn)用戶(hù)登錄等操作

在view中的具體代碼如下

class LoginView(View):

  def get(self,request):
    #邏輯代碼
    return render(request,'login.html')

  def post(self,request):
    # 獲取前端傳遞過(guò)來(lái)的用戶(hù)名和密碼
    username = request.POST.get('username')
    pwd = request.POST.get('pwd')
    record = request.POST.get('record')
    # 進(jìn)行數(shù)據(jù)校驗(yàn)
    if not all([username,pwd]):
      return HttpResponse('數(shù)據(jù)輸入不完整')
    # 驗(yàn)證用戶(hù)名和密碼是否正確
    user = authenticate(username=username,password=pwd)
    return render(request,''index.html')

主要就是其中的user = authenticate(username=username,password=pwd)

兩個(gè)參數(shù)都是拿到前端用戶(hù)輸入的信息

以上這篇Django User 模塊之 AbstractUser 擴(kuò)展詳解就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持億速云。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI