覆盖Django get_or_create

lov*_*ing 6 python django subclass django-models django-managers

我有一个模型,我覆盖了save方法,以便该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
Run Code Online (Sandbox Code Playgroud)

我的想法是为需要与帐户关联的对象设置基本模型,然后我不必在每次出现时处理帐户连接(这很多).

但是:我也想使用get_or_create,它保存新对象而不传递请求.我知道不可以使用get_or_create和做一个try/ except而不是,但我想知道是否有一种方法可以覆盖,get_or_create以及正确的方法是什么.

我查看了代码Manager(我正在考虑重写),该get_or_create函数只调用一个QuerySet.get_or_create函数.也许我可以写它来使用其他管理器功能而不是QuerySet版本的get_or_create?你们都在想什么?

DrM*_*ers 8

您可以继承django.db.models.query.QuerySet并覆盖get_or_create那里的方法来接受您的request关键字参数并将其传递给save我猜,但它不是很漂亮.

class AccountQuerySet(models.query.QuerySet):
    def get_or_create(...):
        ...
Run Code Online (Sandbox Code Playgroud)

然后,您可以将自定义管理器添加到Account使用此自定义的模型中QuerySet:

class AccountManager(models.Manager):
    def get_queryset(self):
        return AccountQuerySet(self.model)
Run Code Online (Sandbox Code Playgroud)

然后在您的模型中使用此管理器:

class Account(models.Model):
    ...
    objects = AccountManager()
Run Code Online (Sandbox Code Playgroud)

但你可能会发现这个try-except方法毕竟更整洁了:)

  • _“是不是很漂亮”_?我认为你的_是_一个巧妙的解决方案。没有它,你需要保持一个纪律,不要在任何地方为这个特定模型使用`get_or_create`,这对我来说听起来很危险。 (3认同)