Python中如何对Django Model进行扩展

写了个 function ,如何让该方法成为所有 model 的成员函数,而不是每个 model 都写一遍
Python中如何对Django Model进行扩展

3 回复

在Django里扩展Model,最直接的方法是用继承。主要有三种方式,看你的具体需求来选。

1. 抽象基类 (Abstract Base Class) 当你有一堆Model都有相同的字段(比如created_at, updated_at),就用这个。它不会在数据库里创建自己的表,它的字段会“注入”到子类里。

from django.db import models

class TimeStampedModel(models.Model):
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        abstract = True  # 关键在这里,这是个抽象基类

class Article(TimeStampedModel):
    title = models.CharField(max_length=200)
    content = models.TextField()
# Article 表里会有 title, content, created_at, updated_at 四个字段

2. 多表继承 (Multi-table Inheritance) 这个会为父类和每个子类都创建一张数据库表,它们之间通过一个自动创建的OneToOneField链接。适合“是一个”的关系,比如Car是一种Vehicle。但用多了JOIN查询可能会慢。

class Vehicle(models.Model):
    manufacturer = models.CharField(max_length=100)

class Car(Vehicle):
    doors = models.IntegerField()
# 数据库里会有 vehicle 表和 car 表,car 表通过一个指向 vehicle 表的外键关联

3. 代理模型 (Proxy Model) 这个最轻量。它和原Model操作同一张数据库表,但你可以给它定义不同的Meta选项(比如默认排序)或添加新的方法。用来改变Model的行为,而不是结构。

class Article(models.Model):
    title = models.CharField(max_length=200)
    published = models.BooleanField(default=False)

class PublishedArticleManager(models.Manager):
    def get_queryset(self):
        return super().get_queryset().filter(published=True)

class PublishedArticle(Article):
    objects = PublishedArticleManager() # 自定义管理器,只返回已发布的文章
    class Meta:
        proxy = True  # 关键在这里,这是个代理模型
        ordering = ['-id'] # 可以定义不同的默认排序
# PublishedArticle 和 Article 操作的是同一张表,但 PublishedArticle.objects.all() 只返回 published=True 的记录

总结一下:

  • 复用字段,用抽象基类
  • 要建立对象间“是一个”的层级关系,用多表继承(注意性能)。
  • 改变某个Model的查询行为或管理器,用代理模型

选哪个取决于你想干嘛。


继承呀

把这个 function 放进一个 class 里 然后所有 model 都继承一下

回到顶部