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 都继承一下

