Можете ли вы объяснить странное поведение с Django ManyToManyField? - PullRequest
0 голосов
/ 10 мая 2011

У меня есть пара связанных моделей, которые выглядят примерно так:

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), и в присоединительной таблице определенно была создана новая запись, книга_автор.Я также попытался вызвать транзакции транзитного доступа () и подключения (.), Чтобы попытаться обновить представление БД.Нет радостиЛюбые указатели на то, какие вещи могут вызывать странное поведение на производстве, будут с благодарностью приняты.

Одна мысль, которая у меня возникла, заключалась в том, что она как-то связана с третьей связанной моделью, для которой я вручную указалСквозная таблица, что-то вроде этого:

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 голосов
/ 10 мая 2011

Я не уверен, что оператор in обязательно работает в наборах запросов.Не забывайте, что экземпляры модели Django не имеют идентичности, поэтому два объекта, загруженные из БД в двух отдельных операциях, могут иметь разные внутренние идентификаторы, даже если они имеют одинаковый pk.

Я бы явно запросил элементвы ожидаете:

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

Я бы также добавил, что не вижу смысла в этом тесте.Модельные операции Django очень хорошо охватываются собственным набором тестов - вы должны зарезервировать свои юниты / документы для собственной бизнес-логики.

...