深入理解 Django 自定义用户模型

1. 引言

Django 作为一个强大的 Web 框架,内置了用户认证系统。然而,实际项目中我们通常需要扩展用户模型,以满足不同的业务需求。Django 提供了继承 AbstractUser 的方式,让我们能够轻松地定制用户模型。本文将通过一个自定义用户模型的实例,深入解析 Django 自定义用户模型的各个知识点。

2. 自定义用户模型代码示例

下面的代码展示了如何在 Django 中创建一个自定义的用户模型 BlogUser,并添加额外的字段和功能:

复制代码
from django.contrib.auth.models import AbstractUser
from django.db import models
from django.urls import reverse
from django.utils.timezone import now
from django.utils.translation import gettext_lazy as _
from djangoblog.utils import get_current_site

class BlogUser(AbstractUser):
    nickname = models.CharField(_('Nickname'), max_length=100, blank=True)
    creation_time = models.DateTimeField(_('Creation time'), default=now, editable=False)
    last_modify_time = models.DateTimeField(_('Last modified time'), auto_now=True)
    source = models.CharField(_('Source'), max_length=100, blank=True)

    def get_absolute_url(self):
        return reverse('blog:author_detail', kwargs={'author_name': self.username})

    def __str__(self):
        return self.username if self.nickname == '' else self.nickname

    def get_full_url(self):
        site = get_current_site().domain
        return f"https://{site}{self.get_absolute_url()}"

    class Meta:
        ordering = ['-id']
        verbose_name = _('User')
        verbose_name_plural = _('Users')
        get_latest_by = 'id'

3. 自定义用户模型详解

3.1 继承 AbstractUser

BlogUser 继承了 Django 内置的 AbstractUser,这意味着该模型默认具备了 Django 用户认证系统的基础功能,比如用户名、密码、邮箱、权限等字段。同时,它还允许我们在此基础上添加自定义字段,如昵称、创建时间、修改时间等,从而满足项目的需求。

3.2 自定义字段

nickname:

  • 这是用户的昵称字段,类型为 CharField,最大长度为 100,允许为空。我们通过 gettext_lazy 使用国际化支持,_('Nickname') 使得该字段的名称可以在不同语言环境下翻译显示。

creation_time:

  • 该字段记录了用户创建的时间。它是一个 DateTimeField,使用了 default=now 来自动记录用户实例创建时的时间。通过 editable=False 参数,我们确保该字段在用户创建后无法被手动修改。

last_modify_time:

  • 这个字段记录了用户信息最后一次修改的时间。通过 auto_now=True,我们确保每次修改用户信息时,该字段都会自动更新为当前时间。这个字段非常适合记录数据的变更时间。

source:

  • 该字段记录了用户的创建来源。它同样是一个可选的字符串字段,最大长度为 100。创建来源可以帮助追踪用户的来源信息,如是通过网站注册、社交媒体登录还是其他方式创建。

3.3 get_absolute_url 方法

get_absolute_url 是 Django 模型中的一个常见方法,用于生成模型实例的绝对 URL。在本例中,我们通过 reverse 函数生成用户详情页的 URL。reverse 根据视图的名称 'blog:author_detail' 及用户的 username,动态生成 URL。

这种动态生成 URL 的方式避免了硬编码路径,不仅提高了代码的灵活性,还能在 URL 结构发生变化时轻松进行维护。

示例

复制代码
def get_absolute_url(self):
    return reverse('blog:author_detail', kwargs={'author_name': self.username})

当我们调用 get_absolute_url() 时,Django 会生成该用户的详情页 URL,比如 /author/john/

3.4 __str__ 方法

__str__ 方法定义了模型实例的字符串表示。在管理后台或者在调试时,打印模型实例通常会调用此方法。对于用户模型,使用昵称优先作为显示内容,如果用户没有设置昵称,则返回用户名。

示例

复制代码
def __str__(self):
    return self.username if self.nickname == '' else self.nickname

这样一来,当用户有昵称时会显示昵称,如果没有昵称就显示用户名,确保用户模型的展示个性化。

3.5 get_full_url 方法

get_full_url 方法返回了完整的用户详情页 URL,包括了站点的域名。我们通过 get_current_site 函数获取当前站点的域名,并拼接绝对 URL,生成完整的链接。这在前端显示用户详情页或者生成分享链接时非常有用。

示例

复制代码
def get_full_url(self):
    site = get_current_site().domain
    return f"https://{site}{self.get_absolute_url()}"

这个方法生成的 URL 可能是 https://mywebsite.com/author/john/,适合用于页面的完整链接展示。

3.6 Meta

Meta 类用于定义模型的元数据。它可以控制模型的行为,比如数据的默认排序方式、模型在管理后台显示的名称等。

  • ordering : ordering = ['-id'] 表示查询用户时按 ID 降序排列,即最新创建的用户会首先展示。
  • verbose_nameverbose_name_plural : 这些字段定义了模型在管理后台的显示名称。在这里,verbose_name = _('User')verbose_name_plural = _('Users') 确保了单数和复数形式的用户名称可以通过国际化翻译。
  • get_latest_by : 通过 get_latest_by,我们定义了在获取最新记录时以哪个字段为依据。在这里,我们使用了 id 字段来获取最新创建的用户。

4. 自定义用户模型的常见场景

在 Web 应用中,用户模型通常是核心的组成部分,而自定义用户模型的需求在很多场景中都会出现。比如:

  • 博客系统:为用户添加昵称、头像、个人简介等自定义字段,用于展示用户信息。
  • 电商平台:可能需要扩展用户模型以记录用户的地址、购物习惯、订单历史等信息。
  • 社交平台:需要记录用户的注册来源、关注列表、好友等数据。

自定义用户模型为我们提供了极大的灵活性,使得开发者可以根据项目需求灵活调整模型结构。

5. 小结

通过自定义用户模型,Django 提供了强大的扩展能力,使得开发者可以在默认用户模型的基础上添加任意需要的字段和功能。本文详细解读了一个自定义用户模型 BlogUser,展示了如何为用户添加昵称、创建时间、修改时间等字段,并通过 get_absolute_urlget_full_url 实现动态 URL 生成。无论是小型网站还是大型系统,自定义用户模型都能极大地满足不同的业务需求,并提升系统的灵活性和可扩展性。


这篇博客专注于 Django 自定义用户模型的讲解,介绍了具体实现和常见的使用场景。

相关推荐
大模型铲屎官13 分钟前
【Python-Day 14】玩转Python字典(上篇):从零开始学习创建、访问与操作
开发语言·人工智能·pytorch·python·深度学习·大模型·字典
yunvwugua__15 分钟前
Python训练营打卡 Day27
开发语言·python
Stara05111 小时前
基于多头自注意力机制(MHSA)增强的YOLOv11主干网络—面向高精度目标检测的结构创新与性能优化
人工智能·python·深度学习·神经网络·目标检测·计算机视觉·yolov11
那雨倾城2 小时前
使用 OpenCV 将图像中标记特定颜色区域
人工智能·python·opencv·计算机视觉·视觉检测
LuckyTHP5 小时前
java 使用zxing生成条形码(可自定义文字位置、边框样式)
java·开发语言·python
mahuifa6 小时前
(7)python开发经验
python·qt·pyside6·开发经验
学地理的小胖砸8 小时前
【Python 操作 MySQL 数据库】
数据库·python·mysql
安迪小宝8 小时前
6 任务路由与负载均衡
运维·python·celery
Blossom.1188 小时前
使用Python实现简单的人工智能聊天机器人
开发语言·人工智能·python·低代码·数据挖掘·机器人·云计算
lisw058 小时前
Python高级进阶:Vim与Vi使用指南
python·vim·excel