Django self.assertEqual сравнивает 2 новых несохраненных объекта

#python #django

#python #django

Вопрос:

Допустим, у меня есть CustomerProfile модель

 class CustomerProfile(models.Model):
    billing_profile = models.ForeignKey(...)
  

и когда я запускаю assertEqual для 2 несохраненных объектов, возникает AssertionError

 self.assertEqual(
    CustomerProfile(billing_profile=default_profile), 
    CustomerProfile(billing_profile=default_profile)
)
  

Выдает следующую ошибку:

AssertionError: <CustomerProfile: Full Charge None> != <CustomerProfile: Full Charge None>

Я не понимаю, почему, потому что идентификатор экземпляра не был бы заполнен, поскольку он не сохранен.

Ответ №1:

В assertEqual нет специальной поддержки для сравнения моделей Django. Если модели не были сохранены (т. Е. имеют первичный ключ), то они сравниваются по идентификатору (CPython: местоположение в памяти), которое всегда будет разным для двух отдельных несохраненных экземпляров модели, даже если каждое поле одинаковое.

Чтобы сравнить несохраненные экземпляры модели на основе содержимого, вам нужно будет вручную проверить, что данные во всех соответствующих полях равны. У стороннего testfixtures есть помощник для этого: см. django_compare .

Комментарии:

1. но почему сравнение 2 разных списков работает? self.assertEqual(['1'], ['1]) Я проверил, что у обоих разные идентификаторы.

2. Потому что списки не сравниваются по идентификатору. Они реализуют __eq__ метод для сравнения по значению.

3. Понятно, спасибо, что бы вы порекомендовали для тестирования двух разных несохраненных объектов модели?

4. Убедитесь, что все соответствующие данные во всех их полях равны.

5. Этот ответ вообще не соответствует действительности. Существует довольно сложный __eq__ метод для моделей Django, который проверяет с помощью PK, но возвращается к идентификатору, если модели не сохранены, что и происходит здесь.