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__、save、clean、full_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,允许以链式调用的方式构建复杂的数据库查询。
  • 关联查询 :利用ForeignKey、ManyToManyField等关系字段,可以方便地执行关联查询。
  • 聚合和注解:使用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应用。

相关推荐
L·S·P2 小时前
25MB 管理 100+ 种数据库:开源轻量客户端 DBX 介绍与上手
数据库·mysql·开源·database·dbx
笃行3504 小时前
KingbaseES KSQL Developer 的连接管理、数据处理与对象管理
数据库
ha_lydms4 小时前
MaxCompute中加密与解密函数
大数据·数据库·数据仓库·hadoop·dataworks·maxcompute·odps
Shadow(⊙o⊙)5 小时前
MySQL内置函数
数据库·mysql
笃行3505 小时前
金仓 KingbaseES PL/SQL 开发全攻略:异常处理、数据类型、调试优化与过程语句
数据库
快乐的木子李6 小时前
mysql-26.7.0-linux26.7.0下载安装
数据库·mysql
excel7 小时前
prisma 如何处理数据库竞态
前端·数据库·后端
知行产研8 小时前
易控智驾:毛利率跃升17.2个百分点,矿山无人驾驶从“规模换增长“迈入“盈利拐点“
数据库·mysql
千里码aicood8 小时前
基于CART算法的图书分类系统设计与实现
数据库·算法·分类
饺子大魔王的男人8 小时前
Redis 内存和连接异常怎么排查?用 redis_exporter 搭一套可远程抓取的监控链路
数据库·redis·bootstrap