Fil*_*eia 12 django django-models
我想在创建特定django模型的实例时进行额外的初始化.我知道压倒__init__会导致麻烦.我还应该考虑其他什么选择?
更新.其他详细信息:目的是初始化该模型实例所代表的状态机.这个状态机由一个导入的库提供,它的内部状态由我的django-model持久化.我们的想法是,无论何时加载模型,状态机都将使用模型的数据自动初始化.
var*_*tec 17
覆盖__init__可能有效,但这是个坏主意,而不是Django方式.
在Django中执行此操作的正确方法是使用信号.
在这种情况下你感兴趣的是pre_init和post_init.
django.db.models.signals.pre_init无论何时实例化Django模型,都会在模型
__init__()方法的开头发送此信号.
django.db.models.signals.post_init喜欢
pre_init,但是当__init__()method方法完成时会发送这个
所以你的代码应该是这样的
from django.db import models
from django.db.models.signals import post_init
class MyModel(models.Model):
  # normal model definition...
def extraInitForMyModel(**kwargs):
   instance = kwargs.get('instance')
   do_whatever_you_need_with(instance)
post_init.connect(extraInitForMyModel, MyModel)
您也可以将信号连接到Django的预定义模型.
虽然我同意通常有一种比覆盖__init__您想要做的事情更好的方法,但这是可能的,并且在某些情况下它可能会很有用。
下面是一个关于如何正确重写__init__模型方法而不干扰 Django 内部逻辑的示例:
from django.db import models
class Book(models.Model):
    title = models.CharField(max_length=100)
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # add your own logic
文档中建议的两种方法依赖于以任意方式创建的实例:
在模型类上添加一个类方法:
from django.db import models
class Book(models.Model):
    title = models.CharField(max_length=100)
    @classmethod
    def create(cls, title):
        book = cls(title=title)
        # do something with the book
        return book
book = Book.create("Pride and Prejudice")
在自定义管理器上添加一个方法:
class BookManager(models.Manager):
    def create_book(self, title):
        book = self.create(title=title)
        # do something with the book
        return book
class Book(models.Model):
    title = models.CharField(max_length=100)
    objects = BookManager()
book = Book.objects.create_book("Pride and Prejudice")
如果这是你的情况,我会走那条路。如果没有,我会坚持@vartec 的答案。