每次将其保存在Django上时,如何为模型的属性设置特定值?

时间:2018-05-12 00:27:12

标签: python django orm

我有一个遗留项目,可以在框架内使用savebulk_create和其他方法保存模型。

为属性设置特定值的最佳方法是什么,以便每次保存记录时,还会保存新值?此值基于正在保存的实例的其他属性构建。

我提出这个问题是因为我不确定除了savebulk_create以及bulk_create知道这一点之外,Django可以保存所有保存方式:

  

不会调用模型的save()方法,也不会调用pre_save和   post_save信号将不会被发送。

https://docs.djangoproject.com/en/1.8/ref/models/querysets/#bulk-create

4 个答案:

答案 0 :(得分:2)

据我所知,有三种方法可以创建/更新模型实例(数据库表中的记录):

  1. 使用模型实例方法save()
  2. 使用查询集方法create()update()get_or_create()update_or_create()bulk_create()
  3. 使用原始SQL或其他低级方法。
  4. 如果您打算在保存时计算字段的值,则可以覆盖我上面列出的所有方法。

    信号(例如pre_create)不是完整的解决方案,因为在使用bulk_create()时它们不会被触发,因此某些实例可以在没有计算属性的情况下保存。

    没有django方式(我知道)拦截我提到的第三点(原始SQL)。

    您没有详细说明您的使用案例,但(根据您的表格大小和更改频率)也许您也可以尝试:

    1. 运行一个定期过程(可能使用crontab)来更新所有模型实例的计算字段。
    2. 添加一个计算字段的数据库触发器。
    3. 传统数据库或系统或通常无法使用,因此您可能不得不采用次优解决方案。

答案 1 :(得分:0)

您可以使用自定义功能在模型的字段中设置默认值。例如,您的Post模型也有一个字段slug。您希望从slug字段自动生成name字段的默认值。你可以写下你的模型:

class Post(models.Model):

    def generate_slug(self):
        return slugify(self.name)

    name = models.CharField()
    description = models.TextField()
    attachment = models.FileField()
    slug = models.CharField(default=generate_slug)

这样,当您创建新帖子时,将从name字段自动生成子句字段。

答案 2 :(得分:0)

另一种方法是在调用者和模型之间创建一个层(数据库层),以便您可以在其中添加逻辑。这样,您就可以缩小在该层中公开的方法的范围,并控制在数据库对话中应该发生的所有情况。

答案 3 :(得分:-1)

处理此问题的最佳方法是覆盖save方法()。 您也可以使用原始sql查询,这也可以轻松解决您的问题

class Model(model.Model):
    field1=models.CharField()
    field2=models.CharField()
    field3=models.CharField()

    def myfunc (self):
    pass 

        #
    def save(self, *args, **kwargs):
        q =  MyModel.objects.select_related('fields1', 'field2',  'filed2').filter(related_field)
    super(Model, self).save(*args, **kwargs)