重写Model.create()方法?

Django文档仅列举了覆盖save()delete()示例。 不过,我只想在创建模型为我的模型定义一些额外的处理。 对于熟悉Rails的人来说,创建一个:before_create过滤器就相当于。 这可能吗?


覆盖__init__()将导致代码在对象的python表示被实例化时执行。 我不知道rails,但是:before_created过滤器听起来像它是在数据库中创建对象时要执行的代码。 如果要在数据库中创建新对象时执行代码,则应覆盖save() ,检查对象是否具有pk属性。 代码看起来像这样:

def save(self, *args, **kwargs):
    if not self.pk:
        # This code only happens if the objects is
        # not in the database yet. Otherwise it would
        # have pk
    super(MyModel, self).save(*args, **kwargs)

一个如何创建post_save信号的例子(来自http://djangosnippets.org/snippets/500/)

from django.db.models.signals import post_save
from django.dispatch import receiver

@receiver(post_save, sender=User)
def create_profile(sender, instance, created, **kwargs):
    """Create a matching profile whenever a user object is created."""
    if created: 
        profile, new = UserProfile.objects.get_or_create(user=instance)

这里是关于是否最好使用信号或自定义保存方法的深思熟虑的讨论http://www.martin-geber.com/thought/2007/10/29/django-signals-vs-custom-save-method/

在我看来,使用这个任务的信号更健壮,更容易阅读,但更长。


这是旧的,有一个公认的答案,工程(Zach的),更地道一个太(迈克尔Bylstra的),但由于它仍然在谷歌的第一个结果大多数人看, 我认为我们需要一个更加最佳实践现代的Django样式答案在这里

from django.db.models.signals import post_save

class MyModel(models.Model):
    # ...
    @classmethod
    def post_create(cls, sender, instance, created, *args, **kwargs):
        if not created:
            return
        # ...what needs to happen on create

post_save.connect(MyModel.post_create, sender=MyModel)

关键是这样的:

  • 使用信号(在官方文档中阅读更多信息)
  • 使用好的命名空间的方法(如果它是有意义的)...我将它标记为@classmethod而不是@staticmethod因为很可能最终需要在代码中引用静态类成员
  • 如果核心Django会有一个实际的post_create信号,那么即使更干净。 (Imho如果你需要传递布尔参数来改变方法的行为,那应该是2种方法。)

    链接地址: http://www.djcxy.com/p/25377.html

    上一篇: Overriding the Model.create() method?

    下一篇: javax.validation to validate list of values?