2011-05-10 78 views
0

我有几个相关的模型,看起来有点像这样:你能用Django ManyToManyField解释奇怪的行为吗?

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 

正如我说的,我的“真实”的模型更加复杂,我还没有能够在简单的测试中复制这种行为,但任何想要看什么的想法都会受到感谢。

回答

0

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

我会明确地查询项目你期待:

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

我还想补充一点,我没有看到这个测试点。 Django的模型操作由其自己的测试套件覆盖得很好 - 您应该为自己的业务逻辑保留您的单元/文档测试。

+0

'in'确实与查询集 – 2011-05-10 21:22:07

+0

商定的工作 - 对象表示相同的DB项目可能有不同的蟒蛇内部ID,但该做的比较平等的,因为__eq__适用于比较PK的 – hwjp 2011-05-11 21:16:35

+0

,并且对于Django的我不会写测试低层次的模型操作,如果他们按照他们应该的方式行事! – hwjp 2011-05-11 21:17:14

相关问题