【问题标题】:django model on_delete pass self to models.SET()django model on_delete 将 self 传递给 models.SET()
【发布时间】:2016-04-27 09:47:11
【问题描述】:

例如,我有一个 Book 模型,每本书都有其作者和标签。

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))

我想,当删除一个标签项目时,书的标签将被设置为其作者的第一个标签。这个怎么做?谢谢。 文档页面 - https://docs.djangoproject.com/en/1.9/ref/models/fields/#django.db.models.SET

更新。 信号没有帮助

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

更新2 最终的工作解决方案是: (脏,但有效)

@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()

【问题讨论】:

    标签: django django-models


    【解决方案1】:

    SET() 不接受任何参数,因此您应该使用signal 接收器:

    from django.db.models.signals import 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 或确保在启动时导入您放入接收器的文件,以便接收器实际连接。

    【讨论】:

    • 为什么?有什么问题吗?
    • @ArthurSult 每次删除时,您的解决方案都会遍历 Book 的所有实例
    • @AlexMorozov from django.db.models.signals.pre_delete 应该是 from django.db.models.signals import pre_delete 吗?接下来,这是在我的模型中定义为类方法还是与我的模型处于同一级别的对等函数?换句话说,第 1 列中的 def 是缩进的还是缩进的?
    猜你喜欢
    • 2016-08-02
    • 1970-01-01
    • 2021-12-27
    • 2016-04-27
    • 2012-03-09
    • 2021-12-23
    • 2021-09-12
    相关资源
    最近更新 更多