Единичный тест Django не будет обновлять BooleanField

Общий ответ: += пытается вызвать специальный метод __iadd__, а если он недоступен, он пытается использовать __add__. Таким образом, проблема заключается в различии между этими специальными методами.

Специальный метод __iadd__ предназначен для дополнения на месте, то есть он мутирует объект, на котором он действует. Специальный метод __add__ возвращает новый объект и также используется для стандартного оператора +.

Поэтому, когда оператор += используется для объекта, у которого __iadd__ определен объект изменен на месте. В противном случае вместо этого попытается использовать plain __add__ и вернуть новый объект.

Вот почему для изменяемых типов, таких как списки +=, изменяется значение объекта, тогда как для неизменяемых типов, таких как кортежи, строки и целые числа вместо этого возвращаются новый объект (a += b становится эквивалентным a = a + b).

Для типов, которые поддерживают как __iadd__, так и __add__, вы должны быть осторожны, какой из них вы используете. a += b вызывается __iadd__ и мутирует a, тогда как a = a + b создаст новый объект и назначит его a. Это не то же самое действие!

>>> a1 = a2 = [1, 2]
>>> b1 = b2 = [1, 2]
>>> a1 += [3]          # Uses __iadd__, modifies a1 in-place
>>> b1 = b1 + [3]      # Uses __add__, creates new list, assigns it to b1
>>> a2
[1, 2, 3]              # a1 and a2 are still the same list
>>> b2
[1, 2]                 # whereas only b1 was changed

Для неизменяемых типов (где у вас нет __iadd__) a += b и a = a + b эквивалентны. Это позволяет использовать += для неизменяемых типов, что может показаться странным конструктивным решением, пока вы не подумаете, что в противном случае вы не могли бы использовать += для неизменяемых типов, таких как числа!

1
задан Christopher Chough 13 July 2018 в 17:19
поделиться

1 ответ

Объект в вашем тестовом методе не обновлен. Вы можете использовать метод refresh_from_db для обновления после изменений:

def test_can_publish_article_from_POST(self):
    other_article_two = Article.objects.create(name='Test Name One', author=User.objects.get(email='testuser@gmail.com'))
    correct_article_two = Article.objects.create(name='Test Name Two', author=User.objects.get(email='testuser@gmail.com'))

    response = self.client.post(reverse('publish_article', kwargs={'pk' : correct_article_two.pk}))

    correct_article_two.refresh_from_db() # Add this line

    self.assertEqual(response.status_code, 302)
    self.assertRedirects(response, f'/articles/{correct_article_two.pk}/')
    self.assertEqual(correct_article_two.published, True)
0
ответ дан neverwalkaloner 17 August 2018 в 12:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: