摘要:博客網站的用戶信息并不復雜,因此擴展就足夠了。可以在這個基礎上,擴展為一個美觀詳細的用戶信息頁面。當然最好再給個人信息添加一個入口。沒有對用戶的登錄狀態進行檢查。總結本章使用一對一鏈接的方式,擴展并更新了用戶信息。
可能你已經發現了,Django自帶的User模型非常實用,以至于我們沒有寫用戶管理相關的任何模型。
但是自帶的User畢竟可用的字段較少。比方說非常重要的電話號碼、頭像等都沒有。解決的方法有很多,你可以不使用User,自己從零寫用戶模型;也可以對User模型進行擴展。
博客網站的用戶信息并不復雜,因此擴展User就足夠了。
擴展User模型擴展User模型又有不同的方法。在大多數情況下,使用模型一對一鏈接的方法是比較適合的。
編寫userprofile/models.py如下:
userprofile/models.py from django.db import models from django.contrib.auth.models import User # 引入內置信號 from django.db.models.signals import post_save # 引入信號接收器的裝飾器 from django.dispatch import receiver # 用戶擴展信息 class Profile(models.Model): # 與 User 模型構成一對一的關系 user = models.OneToOneField(User, on_delete=models.CASCADE, related_name="profile") # 電話號碼字段 phone = models.CharField(max_length=20, blank=True) # 頭像 avatar = models.ImageField(upload_to="avatar/%Y%m%d/", blank=True) # 個人簡介 bio = models.TextField(max_length=500, blank=True) def __str__(self): return "user {}".format(self.user.username) # 信號接收函數,每當新建 User 實例時自動調用 @receiver(post_save, sender=User) def create_user_profile(sender, instance, created, **kwargs): if created: Profile.objects.create(user=instance) # 信號接收函數,每當更新 User 實例時自動調用 @receiver(post_save, sender=User) def save_user_profile(sender, instance, **kwargs): instance.profile.save()
每個Profile模型對應唯一的一個User模型,形成了對User的外接擴展,因此你可以在Profile添加任何想要的字段。這種方法的好處是不需要對User進行任何改動,從而擁有完全自定義的數據表。模型本身沒有什么新的知識,比較神奇的是用到的信號機制。
Django包含一個“信號調度程序”,它可以在框架中的某些位置發生操作時,通知其他應用程序。簡而言之,信號允許某些發送者通知一組接收器已經發生了某個動作。當許多代碼可能對同一事件感興趣時,信號就特別有用。
這里引入的post_save就是一個內置信號,它可以在模型調用save()方法后發出信號。
有了信號之后還需要定義接收器,告訴Django應該把信號發給誰。裝飾器receiver就起到接收器的作用。每當User有更新時,就發送一個信號啟動post_save相關的函數。
通過信號的傳遞,實現了每當User創建/更新時,Profile也會自動的創建/更新。
當然你也可以不使用信號來自動創建Profile表,而是采用手動方式實現。重建數據庫為什么刪除User表不需要信號?答案是兩者的關系采用了models.CASCADE級聯刪除,已經帶有關聯刪除的功能了。
avatar字段用來存放頭像,暫且不管它,下一章講解。
前面講過,每次改動模型后都需要進行數據的遷移。由于avatar字段為圖像字段,需要安裝第三方庫Pillow來支持:
(env) E:django_projectmy_blog> pip install Pillow
安裝成功后,通過makemigrations、migrate遷移數據:
(env) E:django_projectmy_blog>python manage.py makemigrations Migrations for "userprofile": userprofilemigrations