你能用Django ManyToManyField解释奇怪的行为吗?

时间:2011-05-10 08:12:59

标签: django sqlite django-models transactions many-to-many

我有几个相关的模型,看起来有点像这样:

class Book(models.Model):
    title = models.TextField()

class Author(models.Model):
    """
    >>> b = Book(title='some title')
    >>> b.save()
    >>> a = Author(name='some name')
    >>> a.save()
    >>> a.books.add(b)
    >>> b in a.books.all()
    True
    """
    name = models.TextField()
    books = models.ManyToManyField(Book)

这个版本是我的生产应用程序的简化版本,但生产中的相同测试失败 - a.books.all()返回空列表,即使在我执行a.books.add(b)之后。

我查看了数据库(sqlite),并且在连接表book_author中确实创建了一个新条目。我也尝试调用transaction.commit()和connection.close()来尝试刷新数据库的视图。没有快乐。我们非常感激地接受任何可能引起生产中奇怪行为的指示。

我有一个想法是它与第三个相关模型有关,为此我手动指定了一个直通表,如下所示:

class Genre(models.Model): 
    desc = models.TextField() 
    books = models.ManyToManyField(Book, through='BookGenres') 

class BookGenres(models.Model): 
    book = models.ForeignKey(Book) 
    genre = models.ForeignKey(Genre)

然而,将此添加到测试应用程序并不会破坏事物......我还应该寻找什么呢?

[编辑11/5]更奇怪的行为,继续丹尼尔的建议评论(感谢您的尝试!: - )

更奇怪的行为:

>>>a.books.all()
[]
>>>a.books.filter(pk=b.id)
[]
>>>a.books.filter(pk=b.id).count()
1
>>>len(a.books.filter(pk=b.id))
0

正如我所说,我的“真实”模型更复杂,我无法在简化测试中复制这种行为,但任何想看的内容都会感激不尽。

1 个答案:

答案 0 :(得分:0)

我不确定in运算符是否一定适用于查询集。不要忘记Django模型实例没有标识,因此在两个单独的操作中从db加载的两个对象可以具有不同的内部ID,即使它们具有相同的pk。

我会明确地查询您期望的项目:

>>> a.books.add(b)
>>> a.books.filter(pk=b.pk).count()
1

我还补充说,我没有看到这个测试的重点。 Django的模型操作非常适合自己的测试套件 - 您应该为自己的业务逻辑保留单元/文档。