通过Django create方法传递保存参数

时间:2019-12-16 20:16:57

标签: django django-models

假设我有以下Django模型,该模型覆盖了save方法:

class Person(models.Model):
    name = models.CharField(max_length=50)

    def save(self, lock=False, *args, **kwargs):
        if lock:
            print("LOCKING OBJECT...")
        super().save(*args, **kwargs)

我知道我可以创建一个人并将lock传递给save方法,如下所示:

steve = Person(name="Steve")
steve.save(lock=True)
# LOCKING OBJECT...

但是,我真的很喜欢使用create方法,因为它更具可读性:

Person.objects.create(name="Michelle")

如何使用后一种方法通过lock?以下内容无效:

Person.objects.create(name="Michelle", lock=True)
# TypeError: Person() got an unexpected keyword argument 'lock'

2 个答案:

答案 0 :(得分:3)

您可以通过为模型创建自定义管理器来向“人”管理器(objects对象)添加其他方法:

class PersonManager(models.Manager):
    def create_person(*args, **kwargs):
        lock = kwargs.pop('lock', False)
        new_person = self.model(**kwargs)
        new_person.save(lock=lock)
        return new_person

然后将该新经理添加到您的模型中:

class Person(models.Model):
    name = models.CharField(max_length=50)

    objects = PersonManager() #Here!

    def save(self, lock=False, *args, **kwargs):
        if lock:
            print("LOCKING OBJECT...")
        super().save(*args, **kwargs)

现在您可以打电话

Person.objects.create_person(name='Pablo', lock=True)

您还可以覆盖函数名称create,但这可能会产生意想不到的效果,所以我不会这样做。

请注意,这是Django应用中的常见模式,例如Auth

答案 1 :(得分:0)

如果要使用create进行此操作,则始终可以通过覆盖模型的构造函数来完成。

class Person(models.Model):
    def __init__(self, *args, **kwargs):
        self._lock = kwargs.pop('lock', False)
        super().__init__(*args, **kwargs)

    def save(self, *args, **kwargs):
        lock = kwargs.pop('lock', self._lock)
        if lock:
            print("LOCKING OBJECT...")
        super().save(*args, **kwargs)

现在这可以使用

Person.objects.create_person(name='Pablo', lock=True)

steve = Person(name="Steve")
steve.save(lock=True)

请注意,django的官方文档不推荐overriding model's constructor。但是,如果您想做,就可以做。