在运行 Wagtail 项目时,您可能会遇到 RelatedManager 错误:TypeError 'DeferringManyRelatedManager' object is not iterable。

本文将为您介绍如何解决 Wagtail 项目中的 RelatedManager 错误:TypeError 'DeferringManyRelatedManager' object is not iterable。

RelatedManager错误信息

TypeError at /book_a

'DeferringManyRelatedManager' object is not iterable

Request Method:     GET
Request URL:    http://localhost:8000/book_a
Django Version:     4.2.8
Exception Type:     TypeError
Exception Value:    'DeferringManyRelatedManager' object is not iterable

Exception Location:     your_website/models/xx.py, line 202, in get_context
Raised during:  wagtail.views.serve
Python Executable: your_venv/bin/python

RelatedManager错误分析

DeferringManyRelatedManager 是 RelatedManager 的一种子类型。DeferringManyRelatedManager 用于访问 model 的关联对象(related objects)。当你使用 ForeignKey、ManyToManyField、ParentalKey、ParentalManyToManyField 在两个 model 中定义关联时会自动创建 DeferringManyRelatedManager。

例如 Author 和 Book 两个 model :

class Author(models.Model):
    name = models.CharField(
        max_length=255,
        verbose_name=_("Name"),
    )


class Book(models.Model):
    title = models.CharField(
        max_length=255,
        verbose_name=_("Name"),
    )
    author = ParentalKey(
        Author,
        related_name="books",
        verbose_name=_("Book"),
    )

假设 author 是 Author 类的对象,book 是 Book 类的对象。访问 author.books 或者 book.author 都是访问的 Related Manager。在 Python 3 中 Related Manager 是不可迭代的。

RelatedManager错误解决方法

解决在 Wagtail 中遇到的 RelatedManager 错误 ( TypeError 'DeferringManyRelatedManager' object is not iterable ) 可以调用如下三个方法解决:

  • 调用 .all() 方法获取关联对象的 QuerySet 对象
  • 调用 .iterator() 方法获取一个 QuerySet 的 iterator 对象,而不是 list。这样能够减小内存的使用。
  • 调用 .exists() 方法判断 QuerySet 中是否存在数据库。

根据错误信息中 Exception Location 信息定义出现错误的代码,根据需要调用如上的函数,即可解决您遇到的 DeferringManyRelatedManager 错误。

解决 Wagtail 中的 DeferringManyRelatedManager 错误的示例代码:

author = Author.objects.get(id=1)
if author.books.exists():
    for book in author.books.all():
        print(book.title)

或者

author = Author.objects.get(id=1)
if author.books.exists():
    for book in author.books.iterator():
        print(book.title)

结语

本文为您介绍了 .all() , .iterator() , .exists() 三个方法解决 Wagtail 项目中的 RelatedManager 错误:TypeError 'DeferringManyRelatedManager' object is not iterable。