Тестирование Django и значение contentType универсальных приспособлений relatations
Как я использую GenericRelations в модульном тестировании Django?
Я прочитал и попробовал бесчисленные предложения в интернете, но безрезультатно.
Этот был многообещающим Проблемы с contenttypes при загрузке фикстура в Django
Но команда "сброс" больше не существует в Django 1.6
Мой проект использует ключ GenericForeign в contentType и внешним ключом для аутентификации.Пользователи. Я сбросил данные только для моего приложения, используя опцию -- natural, но это привело к проблема, когда пользователи не существовали в тестовой базе данных. Теперь я удалил --естественный параметр, а вместо этого сбросил данные для всех 3 приложение приложений, авт, contenttypes. Когда я запускаю тест, я получаю "не удалось загрузить contenttypes.Значение contentType(ПК=50): app_label колонки, модель не уникальна". Я думаю, это связано с тем, что типы контента создаются динамически при импорте моделей.
Используемая команда:
python manage.py dumpdata auth myApp contenttypes --natural --indent=4 > auhtmtmnatural.json
Затем я сбросил myApp, auth оставив contenttypes. Я понял, что с тех пор ContentTypes app db создается динамически, и мои светильники имеют естественные ключи, это должно работать. Это не так.
Теперь я получаю:
DeserializationError: Problem installing fixture 'auhtmtmnatural.json': ContentType matching query does not exist.
Как заставить fixutres с contetypes работать? Лучше использовать настройки и создать объекты в тестировании?
3 ответа:
Существует несколько причин, по которым вы не должны использовать светильники:
- это медленно
- это трудно обновить / поддерживать;
- не является практикой;
Вместо светильников вы должны использовать "макет" приложения, как factory boy:
Я понимаю, что прошло уже больше года с тех пор, как был задан этот вопрос, однако вам (или кому-то еще) может быть интересно узнать, что я смог использовать fixtures при тестировании модели с универсальным внешним ключом ContentType. Однако есть одно предостережение, которое заключается в том, что мне пришлось жестко кодировать content_type_id в тестовых установках, и это, вероятно, немного неустойчиво с точки зрения порядка, в котором ContentTypes создаются в базе данных. (Я начинаю переписывать свои тесты с factory_boy по причинам @Lara упоминалось)
В настоящее время я использую Django 1.8.3, Python 2.7.9.
Ключевой особенностью, по-видимому, является порядок загрузки приспособлений. В моем tests.py у меня есть:
Tests.py:
class MyModelViewTests(TestCase): fixtures = [ 'auth_user.json', 'gfk_model.json', 'my_model.json', ] def test_something(self): # your tests
Выше, gfk_model.json содержит приспособления для модели, содержащей универсальный внешний ключ ContentType. Моя модель.json содержит приспособления для любой модели вашего проекта Django или приложения. Поэтому я сначала создаю экземпляры модели, содержащие универсальные внешние ключи. Это верно, что их записи object_id ссылаются на строки базы данных для my_model, которые еще не существуют, но будут существовать, как только my_model.приспособления загрузкой JSON.
MyModel/models.py
class MyModel(models.Model): book_title = models.TextField() book_isbn = models.CharField(max_length=13)
GFKModel/models.py
class GFKModel(models.Model): content_type = models.ForeignKey(ContentType) object_id = models.PositiveIntegerField() content_object = GenericForeignKey() your_field = models.TextField()
Если я связываю универсальный внешний ключ с одним конкретным типом контента, то я могу получить идентификатор типа контента из базы данных SQL или
content_type_id = ContentType.objects.get_for_model(MyModel).pk
, выполненный в оболочке django (python manage.py shell
). Я тогда жестко закодировал (Юкки я знаю!) идентификатор таким образом получается (13 в моем случае) в моих приспособлениях.Итак, наконец, светильники (полученные из dumpdata, а затем отредактированные) выглядят примерно так
Gfk_model.json
[ { "fields": { "your_field": "Stuff you need to associate with my_model", "object_id": 1, "content_type": 13, }, "model": "myapp.gfk_model", "pk": 1 }, { "fields": { "your_field": "Stuff you need to associate with my_model", "object_id": 2, "content_type": 13, }, "model": "gfk_app.gfk_model", "pk": 2 } ]
My_model.json
[ { "pk": 1, "model": "myapp.my_model", "fields": { "book_name": "How to bath your cat", "book_isbn": "123456", } }, { "pk": 2, "model": "myapp.my_model", "fields": { "book_name": "How About Wednesday?", "book_isbn": "654321", } } ]
В модели gfk_model.в JSON в объект 1 и 2 соответствуют ПКС 1, 2 в my_model.json соответственно. Я также предоставил PKs для экземпляров gkf_model (хотя, возможно, мне это не нужно, я не пытался удалить их).
В общем, это на самом деле было гораздо быстрее заставить его работать, чем написать этот пост!
Также довольно просто заставить тесты GFK работать, просто используя ORM в тестовой установке (). Также прекрасно и с factory_boy.
Если у вас есть несколько различных типов контента, и особенно если они, вероятно, изменят свой pk в таблице contenttypes, я не думаю, что светильники будут очень успешными.