重写Django的get_or_create
我有一个模型,我重写了它的 save
方法,这样在保存数据之前,可以传入一些数据并自动填充一个字段。下面是我的模型:
class AccountModel(models.Model):
account = models.ForeignKey(Account)
def save(self, request=None, *args, **kwargs):
if request:
self.account = request.session['account']
super(AccountModel, self).save(*args, **kwargs)
class Meta:
abstract = True
我的想法是,建立一个基础模型,用于那些需要和账户关联的对象,这样每次出现这些对象时,我就不需要每次都处理账户连接(这真的很麻烦)。
但是,我还想使用 get_or_create
,这个方法可以在不传入请求的情况下保存新对象。我知道可以不使用 get_or_create
,而是用 try
/except
来处理,但我想知道有没有办法重写 get_or_create
,以及正确的做法是什么。
我查看了 Manager
的代码(我想重写的部分),发现 get_or_create
函数只是调用了 QuerySet.get_or_create
函数。也许我可以写一个版本,使用其他管理器的函数,而不是 QuerySet
版本的 get_or_create
?你们觉得怎么样?
1 个回答
21
你可以创建一个新的类,继承自 django.db.models.query.QuerySet
,然后重写里面的 get_or_create
方法,让它可以接受你的 request
这个参数,并把它传递给 save
方法,不过这样做看起来不是特别优雅。
class AccountQuerySet(models.query.QuerySet):
def get_or_create(...):
...
接着,你可以为你的 Account
模型添加一个自定义的管理器,使用这个自定义的 QuerySet
:
class AccountManager(models.Manager):
def get_queryset(self):
return AccountQuerySet(self.model)
然后在你的模型中使用这个管理器:
class Account(models.Model):
...
objects = AccountManager()
不过你可能会发现,使用 try-except
的方法其实更简洁一些 :)