您的位置:

django有NotImplementedError("Bilateral transformations on nested querysets are not implemented.")报错是怎么回事

  发布时间:2023-04-01 11:15:18
报错的原因Django中的错误是因为在使用了嵌套查询集上的双边变换时出现的。当使用上述情况时,会出现因为嵌套的querysets经过处理后会改变原有的queryset,而嵌套的queryset并不能进行这种操作。解决方法是将查询链接在一起, 这样就能保证在同一个queryset上进行过滤了或者是将查询结果转换为python list或者使用 `list`来转换成python list, 然后在python list上进行操作。另外,在复杂的查询场景下,可能需要使用django orm的subquery和exists来进行嵌套查询,这样可以使用原生sql来解决问题,提高查询效率。

报错的原因

Django中的NotImplementedError("Bilateral transformations on nested querysets are not implemented.")错误是因为在使用了嵌套查询集(queryset)上的双边变换(bilateral transformation)时出现的。

这种错误一般出现在下面这种情况:

- 在嵌套查询集上使用了filter,exclude,annotate,aggregate等方法。

- 在使用嵌套查询集(例如在查询结果中的查询集)上进行操作时。

当使用上述情况时,会出现 NotImplementedError,因为嵌套的querysets经过处理后会改变原有的queryset,而嵌套的queryset并不能进行这种操作。

解决方法就是确保对每个单独的查询集进行过滤,聚合或其它的操作。

举个例子,假设你有以下模型:


class Author(models.Model):
    name = models.CharField(max_length=100)
    age = models.IntegerField()
    
class Book(models.Model):
    author = models.ForeignKey(Author, on_delete=models.CASCADE)
    title = models.CharField(max_length=100)
    pages = models.IntegerField()

那么,如果你这样查询:


authors = Author.objects.filter(age__gt=30)
books = Book.objects.filter(author__in=authors)

就会得到 NotImplementedError("Bilateral transformations on nested querysets are not implemented.")

这是因为在 Book 模型中使用了 Author 模型的过滤(filter)操作,需要将 filter 操作应用到同一个 queryset 上。

解决方法是将查询链接在一起, 这样就能保证在同一个queryset上进行过滤了:


books = Book.objects.filter(author__age__gt=30)

或者是将查询结果转换为python list或者使用 `list(queryset)`来转换成python list, 然后在python list上进行操作。

总之,要注意, 不能在嵌套的querysets上进行过滤,聚合或其它的操作。

如何解决

解决 NotImplementedError("Bilateral transformations on nested querysets are not implemented.")错误的方法是:

- 确保对每个单独的查询集进行过滤,聚合或其它的操作

- 将查询链接在一起,这样就能保证在同一个queryset上进行过滤

- 将查询结果转换为python list或者使用 `list(queryset)`来转换成python list, 然后在python list上进行操作

- 以上是常见的解决办法,根据实际情况解决即可

保证在同一个查询集上进行操作,并且使用正确的方式来处理嵌套的查询集, 比如将嵌套的查询集转换成python list,然后在python list上进行操作。

另外,在复杂的查询场景下,可能需要使用django orm的subquery和exists来进行嵌套查询,这样可以使用原生sql来解决问题,提高查询效率。

总之, 为了避免这种错误,建议在使用查询集时仔细检查查询语句,并使用正确的方法来处理嵌套的查询集。

使用例子

这是一个避免使用嵌套查询集的例子:


# 错误的写法
authors = Author.objects.filter(age__gt=30)
books = Book.objects.filter(author__in=authors)

# 正确的写法
books = Book.objects.filter(author__age__gt=30)

这是一个使用 python list 转换的例子:


authors = list(Author.objects.filter(age__gt=30))
books = Book.objects.filter(author__in=authors)

这是一个使用 subquery 和 exists 的例子


from django.db.models import Exists, Subquery

authors = Author.objects.filter(age__gt=30)
subquery = Subquery(authors.values('id'))
books = Book.objects.filter(author__id__exists=subquery)

这些例子仅为简单示例,在实际使用中可能需要根据具体情况做出更改。