2016-01-21 66 views
1

例如,我有一個Book模型,每本書都有其作者和標籤。django model on_delete將自己傳遞給models.SET()

def get_authors_first_tag(book): 
    try: 
     tag = book.author.tags.first() 
    except: 
     return None 
    else: 
     return tag.id 


class Author(models.Model): 
    name = models.CharField(max_length=50) 
    tags = models.ManyToManyField('Tag') 

class Book(models.Model): 
    name = models.CharField(max_length=50) 
    author = models.ForeignKey(Author) 
    tag = models.ForeignKey('Tag', null=True, on_delete=models.SET(get_authors_first_tag)) 

我想要在刪除標籤項時,將書的標籤設置爲其作者的第一個標籤。這個怎麼做?謝謝。 Doc page - https://docs.djangoproject.com/en/1.9/ref/models/fields/#django.db.models.SET

UPDATE。 信號沒有幫助

from django.db.models.signals import post_delete 
from django.dispatch import receiver 

class Book(models.Model): 
    # temporaryly set to NULL on delete, 
    # becouse for my neds I cannot use default behavior (models.CASCADE) 
    tag = models.ForeignKey('Tag', null=True, on_delete=models.SET_NULL) 

@receiver(post_delete, sender=Tag) 
def delete_tag(instance, **kwargs): 
    for book in instance.book_set.all(): 
     try: 
      book.tag = book.author.tags.first() 
      book.save() 
     except: 
      pass 

UPDATE2 最終工作的解決方案是: (髒,但工程)

@receiver(post_delete, sender=Tag) 
def delete_tag(instance, **kwargs): 
    books = Book.objects.all() 
    for book in books: 
     # after Tag item deleting, book.tag is set to None 
     # so if boook's tag is null, get it's author's first tag 
     if not book.tag: 
      book.tag = book.author.tags.first() 
      book.save() 

回答

1

SET()不接受任何參數,所以你應該使用signal接收器:

from django.db.models.signals.pre_delete 
from django.dispatch import receiver 

@receiver(pre_delete, sender=Tag) 
def reset_tag(sender, **kwargs): 
    tag = kwargs['instance'] 
    for book in books.filter(tag=tag): 
     book.tag = book.author.tags.first() 
     book.save() 

將此代碼嵌入到您的models.py中或者確保您將接收器放入的文件在啓動時導入,以便接收器實際連接。

+0

使用信號 - 好主意,但沒有幫助我。 –

+0

爲什麼?有什麼問題嗎? –

+0

請參閱我的更新問題 –