переопределить Django get_or_create - PullRequest
6 голосов
/ 02 марта 2011

У меня есть модель, для которой я переопределил метод 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

Идея состоит в том, чтобы я создал базовую модель для объектов, которые должны быть связаны с учетной записью, и тогда мне не придется иметь дело с подключениями к учетной записи каждый раз, когда они приходятвверх (что много).

Но: я также хотел бы использовать get_or_create, который сохраняет новые объекты без передачи запроса.Я знаю, что выполнимо не использовать get_or_create и вместо этого делать try / except, но я бы хотел знать , если есть способ переопределить get_or_create и как правильно это сделатьсделайте это .

Я посмотрел код для Manager (который я смотрю на переопределение), а функция get_or_create просто вызывает функцию QuerySet.get_or_create.Может быть, я могу написать его, чтобы использовать другие функции менеджера, а не QuerySet версию get_or_create?Что вы думаете?

1 Ответ

8 голосов
/ 03 марта 2011

Вы можете создать подкласс 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 все-таки аккуратнее:)

...