Django - Как сравнить состояние до / после сохранения модели, включая все отношения - PullRequest
1 голос
/ 28 февраля 2012

Я пытаюсь сохранить несколько наборов в Redis, которые отслеживают модели в Django

class Campaign(models.Model):
    advertiser = models.ForeignKey(User)
    name = models.CharField(max_length=200)
    carriers = models.ManyToManyField(Carrier)
    countries = models.ManyToManyField(Country)


@receiver(pre_save, sender=Campaign)
def adserver_clear_cache(sender, **kwargs):
    campaign = kwargs['instance']
    for con in campaign.countries.all():
        r.srem("con:" + str(con.id), campaign.id)
    for car in campaign.carriers.all():
        r.srem("car:" + str(car.id), campaign.id)


@receiver(post_save, sender=Campaign)
def adserver_save_cache(sender, **kwargs):
    campaign = kwargs['instance']
    for con in campaign.countries.all():
        r.sadd("con:" + str(con.id), campaign.id)
    for car in campaign.carriers.all():
        r.sadd("car:" + str(car.id), campaign.id)

Проблема в том, что кампания полностью сохраняется до того, как будут сохранены все носители, кампании и т.п. Поэтому я получаю те же данные в pre + post_save. Есть ли способ вызвать функцию, когда все, включая отношения, сохранено?

спасибо!

Ответы [ 2 ]

3 голосов
/ 29 февраля 2012

Проблема в том, что отношение m2m сохраняется после ваша модель сохранена, другими словами "post_save () еще слишком рано" для того, что вы ищете.

Выможно использовать сигнал m2m_changed в качестве jpic, или использовать новый «save_related» Django 1.4 - https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.save_related, закрывший билет 16115 https://code.djangoproject.com/ticket/16115

См. также https://stackoverflow.com/a/8462541/640759

0 голосов
/ 28 февраля 2012

ManyToManyField является специальным . Он не представлен в базе данных столбцом таблицы своей модели. Фактически, ManyToManyField представляет собой еще одну таблицу , которая связывает модели по обе стороны отношения n: m.

Нет смысла излучать модельный сигнал, такой как post_save, для произвольной стороны отношения n: m. При изменении ManyToManyField выдается сигнал m2m_dered :

Отправляется, когда ManyToManyField изменяется на экземпляре модели. Строго говоря, это не модельный сигнал, поскольку он отправляется ManyToManyField, но поскольку он дополняет pre_save / post_save и pre_delete / post_delete, когда дело доходит до отслеживания изменений в моделях, он включается сюда.

...