Django中如何调用抽象模型的__init__方法?
在Django中调用抽象模型的__init__方法
首先得先确认你的BaseModel是抽象模型——要让它成为抽象模型,必须在内部的Meta类里添加abstract = True,否则它会被当作普通的 concrete 模型处理:
@python_2_unicode_compatible class BaseModel(TimeStampedModel, SoftDeletableModel): user = models.ForeignKey( settings.AUTH_USER_MODEL, related_name='%(class)s_wallet', on_delete=models.CASCADE ) first_field = models.CharField(max_length=5) second_field = models.CharField(max_length=10) # 必须添加这个Meta类标记为抽象模型 class Meta: abstract = True # 这里要修正__init__的参数,Django模型的__init__需要接收*args和**kwargs def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self._set_default_value() # 其他初始化逻辑... def _set_default_values(self): first_field = self.__class__._meta.get_field('first_field') # 你的字段默认值设置逻辑...
接下来分两种场景说明怎么调用抽象模型的__init__:
场景1:子类没有重写__init__方法
如果你的 concrete 模型(继承自BaseModel的子类)没有自己的__init__方法,那么实例化子类时会自动调用抽象模型的__init__,完全不需要额外操作:
# 定义一个继承自BaseModel的具体模型 class Wallet(BaseModel): # 子类的额外字段 balance = models.DecimalField(max_digits=10, decimal_places=2) # 实例化时,BaseModel的__init__会被自动触发 my_wallet = Wallet(user=request.user, balance=100.00)
场景2:子类重写了__init__方法
如果你的子类需要自定义初始化逻辑,必须显式调用super().__init__(*args, **kwargs),这样才能触发抽象模型BaseModel里的初始化逻辑,否则父类的__init__不会执行:
class Wallet(BaseModel): balance = models.DecimalField(max_digits=10, decimal_places=2) def __init__(self, *args, **kwargs): # 先调用BaseModel的__init__,确保父类的初始化逻辑执行 super().__init__(*args, **kwargs) # 再写子类自己的初始化逻辑 self.balance = kwargs.get('balance', 0.00)
另外要注意:你的BaseModel里的__init__原来没有接收*args和**kwargs,这会导致实例化时传参报错——因为Django的模型基类(包括你继承的TimeStampedModel、SoftDeletableModel)的__init__需要这些参数,所以一定要修正BaseModel的__init__参数列表,加上*args, **kwargs。
内容的提问来源于stack exchange,提问作者Narnik Gamarnik
相关产品推荐
相关产品推荐

