Как использовать приемник post_save с django-polymorphic?

python django polymorphism

205 просмотра

1 ответ

863 Репутация автора

У меня есть django-polymorphicмодель, и я хочу реализовать post_saveсигнал для автоматического создания связанной модели, которая также является полиморфной.

Это что-то вроде приведенного ниже кода, соответствующая часть нерабочего кода является @receiverдекорированным work_post_saveметодом. Проблема в том, что экземпляр является ctype_id, а не объектом.

from django.db import models
from django.db.models import signals
from django.dispatch import receiver
from polymorphic.models import PolymorphicModel

from mygallery.models import Album

# Work Parent PolymorphicModel
class Work(PolymorphicModel):
    title = models.CharField(blank=True,max_length=256)
    slug = models.SlugField(max_length=256)

@receiver(signals.post_save, sender=Work)
def work_post_save(sender, instance, signal, created, **kwargs):
    album, new = Album.objects.get_or_create(title=instance.title + ' Stills', slug=instance.slug + '-stills')
    work_album, new = WorkAlbum.objects.get_or_create(work=instance, album=album, is_key=True)


class ArtProject(Work):
    manifesto = models.CharField(blank=True,max_length=256)

class CodeProject(Work):
    code = models.CharField(blank=True,max_length=256)


# Content Parent PolymorphicModel
class WorkContent(PolymorphicModel):
    is_key = models.BooleanField(default=False, unique=True, default=False)


class WorkAlbum(WorkContent):
    work = models.ForeignKey(Work, related_name='work_albums')
    album = models.ForeignKey(Album, related_name='album_works')
Автор: robertmoggach Источник Размещён: 17.07.2016 09:57

Ответы (1)


0 плюса

361 Репутация автора

Я только немного поиграл с этим, поэтому я не уверен на 100%, как правильно с этим справиться.

То, что я в итоге сделал, это чтобы не объявить senderв @receiverаннотации. Это приводит к тому, что обратный вызов запускается каждым post_saveсигналом. Затем в обратном вызове я проверяю isinstance()свою родительскую модель (в вашем случае Work), чтобы обратный вызов выполнялся только после сохранения интересующей меня модели. Когда выполняется обратный вызов, instanceпараметр является дочерней моделью (в вашем случае ArtProjectили CodeProject).

@receiver(signals.post_save)
def work_post_save(sender, instance, signal, created, **kwargs):
    if isinstance(instance, Work):
        # instance is either ArtProject or CodeProject
        album, new = Album.objects.get_or_create(title=instance.title + ' Stills', slug=instance.slug + '-stills')
        work_album, new = WorkAlbum.objects.get_or_create(work=instance, album=album, is_key=True)

Запуск непосредственно на родителя save(), очевидно, не поддерживается .

Автор: TehQuila Размещён: 15.03.2017 08:50
Вопросы из категории :
32x32