最近在寫博客,剛好寫到用戶註冊註銷模塊,覺得這一方面還是挺有趣的。當嘗試掀開 Django 的源代碼時一切 API 就不會變得那麼摸不着。順着讀Django 的各模塊源碼,我們可以更靈活地更改代碼以實現自己想要的功能。
現在,思考一個問題,主需求是實現博客中用戶的註冊登錄登出功能。如果只滿足於用戶註冊時只登記其郵箱或是用戶名,Django 自帶的 User 模塊既可以實現。但實際上,一個普遍的要求是註冊用戶應該能夠修改自己的頭像信息,郵箱信息,暱稱信息等其他更靈活的需求。
可以先看一下 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 模塊實際上繼承了 AbstractUser 模塊,AbstractUser 模塊下有 :
- username
- first_name
- last_name
- date_joined
…
你可以看出,User
模塊繼承了 AbstractUser
抽象基類,而僅僅只是繼承了,並沒有對 AbstractUser 進行任何擴展。所以,對於一個需要更多需求的 User 模塊信息來說,我們可以繼承 AbstractUser
並根據自己的需求進行擴展。
現在,我們對用戶屬性添加一些需求,比如支持用戶修改頭像、支持用戶暱稱、qq、wechat 以及網站鏈接等。
class User(AbstractUser):
nickname = models.CharField(max_length=30, blank=True, null=True, verbose_name='暱稱')
qq = models.CharField(max_length=20, blank=True, null=True, verbose_name='QQ號碼')
url = models.URLField(max_length=100, blank=True, null=True, verbose_name='個人網頁地址')
avatar = ProcessedImageField(upload_to='avatar',
default='avatar/default.png', verbose_name='頭像')
class Meta:
verbose_name = '用戶'
verbose_name_plural = verbose_name
ordering = ['-id']
def __str__(self):
return self.username
我們給自定義的用戶模塊增加 nickname(暱稱), qq, url(網站鏈接),avatar(頭像)屬性。
注意:爲了讓 Django 能夠識別使用自定義的用戶模型,必須要在 settings.py
中設置自定義模塊位置,如在 settings.py
上添加
AUTH_USER_MODEL = 'blog.user'
其中,blog
爲你對應的應用 app 信息,user 爲 blog 應用下的 user
模塊,在這裏 blog
和 user
大小寫無關。
如果在你現在執行數據庫遷移命令,可能會出現 blog 不存在 user 模塊 的提示,而無法重新進行數據遷移。
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
的用戶模型,並重新將其自定義爲 AUTH_USER_MODEL = blog.user
請刪掉 migrations
目錄下的所有文件 以及數據庫文件。
刪除之後,重新進行數據庫的遷移
$ python manage.py makemigrations myapp
$ python manage.py migrate
這個時候,所使用的用戶即爲自定義後的用戶了。
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
這裏可以在模板中指定數據庫 db_table = 'user'