Django 模型

Django 模型

在Django框架中,模型(Model)是ORM(对象关系映射)的核心,它允许开发者以面向对象的方式操作数据库。模型类定义了数据库表的结构,每个实例代表表中的一行记录。在前面的基础上,我们将进一步扩写模型相关的内容,包括模型继承、自定义管理器、信号以及模型的生命周期等。

1. 模型继承

Django支持模型的继承,这有助于代码重用和逻辑组织。模型继承分为抽象基类模型和多态模型两种。

  • 抽象基类模型 :使用Meta类中的abstract = True声明。这种模型不会直接对应数据库中的表,而是作为其他模型的基类,提供共享字段和方法。
python 复制代码
from django.db import models

class AbstractPerson(models.Model):
    name = models.CharField(max_length=100)
    
    class Meta:
        abstract = True

class Student(AbstractPerson):
    # Student模型将继承AbstractPerson的所有字段,并可以添加自己的字段
    grade = models.CharField(max_length=2)
  • 多态模型 :通过第三方包如django-polymorphic实现,允许一个基类对应多个子类,并在查询时返回具体的子类实例。
2. 自定义管理器

管理器(Manager)是Django模型与数据库查询之间的接口。每个模型至少有一个管理器,默认是objects。通过自定义管理器,可以封装复杂的查询逻辑,使模型的使用更加直观。

python 复制代码
from django.db import models

class CustomManager(models.Manager):
    def get_active_students(self):
        # 假设有一个is_active字段表示学生是否活跃
        return self.filter(is_active=True)

class Student(models.Model):
    name = models.CharField(max_length=100)
    is_active = models.BooleanField(default=True)
    objects = CustomManager()
3. 信号(Signals)

Django信号允许在模型保存、删除等操作时自动执行特定函数。这对于实现如自动日志记录、用户通知等功能非常有用。

python 复制代码
from django.db.models.signals import post_save, pre_delete
from django.dispatch import receiver
from .models import Student

@receiver(post_save, sender=Student)
def student_post_save(sender, instance, created, **kwargs):
    if created:
        # 当新学生创建时执行的操作
        print(f"New student created: {instance.name}")

@receiver(pre_delete, sender=Student)
def student_pre_delete(sender, instance, **kwargs):
    # 在学生删除前执行的操作
    print(f"Student {instance.name} is about to be deleted")
4. 模型的生命周期

理解模型实例的生命周期对于调试和优化至关重要。模型实例从创建到保存(或删除)的过程中,会触发一系列方法,如__init__savecleanfull_clean等。

  • __init__:实例初始化时调用。
  • save :保存或更新实例时调用。可以通过重写save方法添加自定义逻辑。
  • clean :在调用full_clean时自动调用,用于验证字段值。
  • full_clean:在保存之前验证模型字段的完整性,包括唯一性、必填性等。
python 复制代码
class Student(models.Model):
    # ... 字段定义 ...

    def clean(self):
        # 自定义验证逻辑
        if self.age < 0:
            raise ValidationError({'age': "Age cannot be negative"})

    def save(self, *args, **kwargs):
        # 自定义保存逻辑
        self.full_clean()  # 强制验证
        super().save(*args, **kwargs)
5. 模型的进阶用法
  • 查询集(QuerySet):Django提供了强大的查询API,允许以链式调用的方式构建复杂的数据库查询。
  • 关联查询 :利用ForeignKeyManyToManyField等关系字段,可以方便地执行关联查询。
  • 聚合和注解:使用Django的聚合函数和注解功能,可以在数据库层面进行数据统计和计算。
python 复制代码
# 示例:统计每个班级的学生人数
from django.db.models import Count

grade_counts = Student.objects.values('grade').annotate(count=Count('id'))
for grade_count in grade_counts:
    print(f"Grade {grade_count['grade']} has {grade_count['count']} students")

通过深入理解和应用Django模型,开发者可以更加高效地管理数据库,构建出功能丰富、性能优异的Web应用。

相关推荐
共享家95277 分钟前
Linux常用命令详解:从基础到进阶
linux·服务器·数据库
我是个假程序员4 小时前
sql server数据库可疑修复
数据库
极限实验室6 小时前
如何使用 Nginx 代理 Easysearch 服务
数据库·nginx
whn19776 小时前
selectdb修改表副本
数据库
TDengine (老段)6 小时前
TDengine 中的视图
数据库·物联网·oracle·时序数据库·tdengine·iotdb
Kyrie_Li7 小时前
Redis-Sentinel(哨兵模式)
数据库·redis·sentinel
计算机毕设定制辅导-无忧学长8 小时前
TDengine 数据写入优化:协议选择与批量操作(一)
网络·数据库·tdengine
Mr.洛 白8 小时前
OpenEuler/CentOS一键部署OpenGauss数据库教程(脚本+视频)
数据库·opengauss·gaussdb·国产数据库安装·安装脚本
炬火初现8 小时前
redis-cpp-cpp如何使用lua脚本
数据库·redis·lua
hxung8 小时前
Redis 数据类型详解
数据库·redis·缓存