From 9c19aff7c7561e3a82978a272ecdaad40dda5c00 Mon Sep 17 00:00:00 2001 From: django-bot Date: Thu, 3 Feb 2022 20:24:19 +0100 Subject: Refs #33476 -- Reformatted code with Black. --- tests/absolute_url_overrides/tests.py | 42 +- tests/admin_autodiscover/tests.py | 5 +- tests/admin_changelist/admin.py | 92 +- tests/admin_changelist/models.py | 12 +- tests/admin_changelist/test_date_hierarchy.py | 71 +- tests/admin_changelist/tests.py | 1200 ++-- tests/admin_changelist/urls.py | 2 +- tests/admin_checks/models.py | 6 +- tests/admin_checks/tests.py | 389 +- tests/admin_custom_urls/models.py | 24 +- tests/admin_custom_urls/tests.py | 96 +- tests/admin_custom_urls/urls.py | 2 +- tests/admin_default_site/apps.py | 4 +- tests/admin_default_site/tests.py | 25 +- tests/admin_docs/models.py | 9 +- tests/admin_docs/namespace_urls.py | 15 +- tests/admin_docs/test_middleware.py | 49 +- tests/admin_docs/test_utils.py | 70 +- tests/admin_docs/test_views.py | 445 +- tests/admin_docs/tests.py | 17 +- tests/admin_docs/urls.py | 23 +- tests/admin_filters/models.py | 49 +- tests/admin_filters/tests.py | 1008 ++-- tests/admin_inlines/admin.py | 150 +- tests/admin_inlines/models.py | 66 +- tests/admin_inlines/test_templates.py | 24 +- tests/admin_inlines/tests.py | 1443 +++-- tests/admin_inlines/urls.py | 8 +- tests/admin_ordering/models.py | 13 +- tests/admin_ordering/tests.py | 83 +- tests/admin_registration/tests.py | 35 +- .../migrations/0001_initial.py | 17 +- .../another_app_waiting_migration/models.py | 2 +- tests/admin_scripts/app_raising_messages/models.py | 6 +- tests/admin_scripts/app_raising_warning/models.py | 2 +- .../migrations/0001_initial.py | 17 +- .../admin_scripts/app_waiting_migration/models.py | 2 +- .../complex_app/management/commands/duplicate.py | 3 +- tests/admin_scripts/complex_app/models/__init__.py | 2 +- tests/admin_scripts/complex_app/models/bar.py | 2 +- tests/admin_scripts/complex_app/models/foo.py | 2 +- .../configured_dynamic_settings_manage.py | 8 +- tests/admin_scripts/configured_settings_manage.py | 2 +- .../management/commands/app_command.py | 7 +- .../management/commands/base_command.py | 15 +- .../management/commands/custom_startproject.py | 4 +- .../management/commands/label_command.py | 5 +- .../management/commands/noargs_command.py | 2 +- .../commands/suppress_base_options_command.py | 22 +- .../simple_app/management/commands/duplicate.py | 3 +- tests/admin_scripts/simple_app/models.py | 2 +- tests/admin_scripts/tests.py | 1486 ++--- tests/admin_scripts/urls.py | 7 +- tests/admin_utils/admin.py | 8 +- tests/admin_utils/models.py | 13 +- tests/admin_utils/test_logentry.py | 214 +- tests/admin_utils/tests.py | 270 +- tests/admin_utils/urls.py | 2 +- tests/admin_views/admin.py | 727 ++- tests/admin_views/custom_has_permission_admin.py | 14 +- tests/admin_views/customadmin.py | 33 +- tests/admin_views/forms.py | 11 +- tests/admin_views/models.py | 238 +- tests/admin_views/test_actions.py | 414 +- tests/admin_views/test_adminsite.py | 72 +- tests/admin_views/test_autocomplete_view.py | 442 +- tests/admin_views/test_forms.py | 25 +- tests/admin_views/test_history_view.py | 79 +- tests/admin_views/test_multidb.py | 38 +- tests/admin_views/test_nav_sidebar.py | 187 +- tests/admin_views/test_templatetags.py | 147 +- tests/admin_views/tests.py | 5981 ++++++++++++-------- tests/admin_views/urls.py | 42 +- tests/admin_views/views.py | 2 +- tests/admin_widgets/models.py | 45 +- tests/admin_widgets/test_autocomplete_widget.py | 144 +- tests/admin_widgets/tests.py | 1154 ++-- tests/admin_widgets/urls.py | 2 +- tests/admin_widgets/widgetadmin.py | 39 +- tests/aggregation/models.py | 4 +- tests/aggregation/test_filter_argument.py | 179 +- tests/aggregation/tests.py | 1790 +++--- tests/aggregation_regress/models.py | 22 +- tests/aggregation_regress/tests.py | 1683 +++--- tests/annotations/models.py | 6 +- tests/annotations/tests.py | 1234 ++-- tests/app_loading/not_installed/models.py | 9 +- tests/app_loading/tests.py | 46 +- tests/apps/apps.py | 20 +- tests/apps/models.py | 2 +- tests/apps/namespace_package_base/nsapp/apps.py | 2 +- tests/apps/one_config_app/apps.py | 2 +- tests/apps/tests.py | 241 +- tests/apps/two_configs_app/apps.py | 4 +- tests/apps/two_configs_one_default_app/apps.py | 4 +- tests/apps/two_default_configs_app/apps.py | 4 +- tests/asgi/tests.py | 177 +- tests/asgi/urls.py | 16 +- tests/async/tests.py | 25 +- tests/auth_tests/backend_alias.py | 2 +- tests/auth_tests/client.py | 6 +- tests/auth_tests/models/__init__.py | 33 +- tests/auth_tests/models/custom_permissions.py | 9 +- tests/auth_tests/models/custom_user.py | 31 +- tests/auth_tests/models/invalid_models.py | 5 +- tests/auth_tests/models/is_active.py | 3 +- tests/auth_tests/models/minimal.py | 2 +- tests/auth_tests/models/no_password.py | 2 +- tests/auth_tests/models/proxy.py | 8 +- tests/auth_tests/models/uuid_pk.py | 2 + tests/auth_tests/models/with_custom_email_field.py | 4 +- tests/auth_tests/models/with_foreign_key.py | 12 +- tests/auth_tests/models/with_integer_username.py | 4 +- tests/auth_tests/models/with_many_to_many.py | 10 +- tests/auth_tests/settings.py | 30 +- tests/auth_tests/test_admin_multidb.py | 27 +- tests/auth_tests/test_auth_backends.py | 505 +- tests/auth_tests/test_basic.py | 75 +- tests/auth_tests/test_checks.py | 374 +- tests/auth_tests/test_context_processors.py | 64 +- tests/auth_tests/test_decorators.py | 68 +- tests/auth_tests/test_forms.py | 891 +-- tests/auth_tests/test_handlers.py | 46 +- tests/auth_tests/test_hashers.py | 708 +-- tests/auth_tests/test_management.py | 888 +-- tests/auth_tests/test_middleware.py | 6 +- tests/auth_tests/test_migrations.py | 138 +- tests/auth_tests/test_mixins.py | 114 +- tests/auth_tests/test_models.py | 330 +- tests/auth_tests/test_remote_user.py | 189 +- tests/auth_tests/test_signals.py | 51 +- tests/auth_tests/test_templates.py | 83 +- tests/auth_tests/test_tokens.py | 57 +- tests/auth_tests/test_validators.py | 179 +- tests/auth_tests/test_views.py | 1168 ++-- tests/auth_tests/urls.py | 180 +- tests/auth_tests/urls_admin.py | 4 +- tests/auth_tests/urls_custom_user_admin.py | 4 +- .../base/app_unmigrated/migrations/0001_initial.py | 14 +- tests/backends/base/app_unmigrated/models.py | 2 +- tests/backends/base/test_base.py | 94 +- tests/backends/base/test_client.py | 8 +- tests/backends/base/test_creation.py | 155 +- tests/backends/base/test_features.py | 3 +- tests/backends/base/test_introspection.py | 12 +- tests/backends/base/test_operations.py | 107 +- tests/backends/base/test_schema.py | 2 +- tests/backends/models.py | 50 +- tests/backends/mysql/test_creation.py | 77 +- tests/backends/mysql/test_features.py | 13 +- tests/backends/mysql/test_introspection.py | 54 +- tests/backends/mysql/test_operations.py | 18 +- tests/backends/mysql/test_schema.py | 15 +- tests/backends/mysql/tests.py | 45 +- tests/backends/oracle/test_creation.py | 65 +- tests/backends/oracle/test_introspection.py | 22 +- tests/backends/oracle/test_operations.py | 24 +- tests/backends/oracle/tests.py | 53 +- tests/backends/postgresql/test_creation.py | 57 +- tests/backends/postgresql/test_introspection.py | 14 +- tests/backends/postgresql/test_operations.py | 2 +- .../postgresql/test_server_side_cursors.py | 38 +- tests/backends/postgresql/tests.py | 115 +- tests/backends/sqlite/test_creation.py | 24 +- tests/backends/sqlite/test_features.py | 8 +- tests/backends/sqlite/test_functions.py | 10 +- tests/backends/sqlite/test_introspection.py | 125 +- tests/backends/sqlite/test_operations.py | 17 +- tests/backends/sqlite/tests.py | 116 +- tests/backends/test_ddl_references.py | 241 +- tests/backends/test_utils.py | 144 +- tests/backends/tests.py | 289 +- tests/bash_completion/tests.py | 49 +- tests/basic/models.py | 13 +- tests/basic/tests.py | 451 +- tests/builtin_server/tests.py | 46 +- tests/builtin_server/urls.py | 2 +- tests/builtin_server/views.py | 4 +- tests/bulk_create/models.py | 46 +- tests/bulk_create/tests.py | 585 +- tests/cache/models.py | 2 +- tests/cache/tests.py | 2041 ++++--- tests/cache/tests_async.py | 149 +- tests/check_framework/apps.py | 6 +- tests/check_framework/models.py | 2 +- .../template_test_apps/different_tags_app/apps.py | 2 +- .../template_test_apps/same_tags_app_1/apps.py | 2 +- .../template_test_apps/same_tags_app_2/apps.py | 2 +- tests/check_framework/test_4_0_compatibility.py | 30 +- tests/check_framework/test_async_checks.py | 4 +- tests/check_framework/test_caches.py | 141 +- tests/check_framework/test_database.py | 30 +- tests/check_framework/test_files.py | 6 +- tests/check_framework/test_model_checks.py | 423 +- .../test_model_field_deprecation.py | 88 +- tests/check_framework/test_multi_db.py | 20 +- tests/check_framework/test_security.py | 182 +- tests/check_framework/test_templates.py | 159 +- tests/check_framework/test_translation.py | 111 +- tests/check_framework/test_urls.py | 239 +- tests/check_framework/tests.py | 159 +- .../urls/bad_error_handlers_invalid_path.py | 8 +- .../urls/bad_function_based_error_handlers.py | 8 +- tests/check_framework/urls/beginning_with_slash.py | 4 +- tests/check_framework/urls/cbv_as_view.py | 6 +- tests/check_framework/urls/contains_tuple.py | 2 +- .../urls/good_function_based_error_handlers.py | 10 +- .../check_framework/urls/include_contains_tuple.py | 2 +- tests/check_framework/urls/include_with_dollar.py | 2 +- tests/check_framework/urls/name_with_colon.py | 2 +- tests/check_framework/urls/no_warnings.py | 13 +- tests/check_framework/urls/no_warnings_i18n.py | 2 +- .../check_framework/urls/non_unique_namespaces.py | 19 +- .../path_compatibility/beginning_with_caret.py | 2 +- .../path_compatibility/contains_re_named_group.py | 2 +- .../urls/path_compatibility/ending_with_dollar.py | 2 +- tests/check_framework/urls/unique_namespaces.py | 30 +- tests/check_framework/urls/warning_in_include.py | 11 +- tests/conditional_processing/tests.py | 245 +- tests/conditional_processing/urls.py | 16 +- tests/constraints/models.py | 53 +- tests/constraints/tests.py | 467 +- tests/contenttypes_tests/models.py | 20 +- .../operations_migrations/0001_initial.py | 4 +- .../operations_migrations/0002_rename_foo.py | 24 +- tests/contenttypes_tests/test_checks.py | 265 +- tests/contenttypes_tests/test_fields.py | 25 +- tests/contenttypes_tests/test_management.py | 68 +- tests/contenttypes_tests/test_models.py | 199 +- tests/contenttypes_tests/test_operations.py | 188 +- tests/contenttypes_tests/test_views.py | 171 +- tests/contenttypes_tests/urls.py | 2 +- tests/context_processors/tests.py | 83 +- tests/context_processors/urls.py | 4 +- tests/context_processors/views.py | 8 +- tests/csrf_tests/csrf_token_error_handler_urls.py | 2 +- tests/csrf_tests/test_context_processor.py | 7 +- tests/csrf_tests/tests.py | 595 +- tests/csrf_tests/views.py | 20 +- tests/custom_columns/models.py | 22 +- tests/custom_columns/tests.py | 65 +- tests/custom_lookups/tests.py | 428 +- tests/custom_managers/models.py | 67 +- tests/custom_managers/tests.py | 401 +- tests/custom_methods/models.py | 9 +- tests/custom_methods/tests.py | 16 +- .../custom_migration_operations/more_operations.py | 6 +- tests/custom_migration_operations/operations.py | 34 +- tests/custom_pk/fields.py | 5 +- tests/custom_pk/models.py | 6 +- tests/custom_pk/tests.py | 99 +- tests/datatypes/models.py | 2 +- tests/datatypes/tests.py | 57 +- tests/dates/tests.py | 37 +- tests/datetimes/models.py | 2 +- tests/datetimes/tests.py | 117 +- tests/db_functions/comparison/test_cast.py | 115 +- tests/db_functions/comparison/test_coalesce.py | 61 +- tests/db_functions/comparison/test_collate.py | 36 +- tests/db_functions/comparison/test_greatest.py | 69 +- tests/db_functions/comparison/test_json_object.py | 105 +- tests/db_functions/comparison/test_least.py | 61 +- tests/db_functions/comparison/test_nullif.py | 40 +- tests/db_functions/datetime/test_extract_trunc.py | 1461 +++-- tests/db_functions/datetime/test_now.py | 21 +- tests/db_functions/math/test_abs.py | 21 +- tests/db_functions/math/test_acos.py | 25 +- tests/db_functions/math/test_asin.py | 25 +- tests/db_functions/math/test_atan.py | 25 +- tests/db_functions/math/test_atan2.py | 17 +- tests/db_functions/math/test_ceil.py | 25 +- tests/db_functions/math/test_cos.py | 21 +- tests/db_functions/math/test_cot.py | 21 +- tests/db_functions/math/test_degrees.py | 25 +- tests/db_functions/math/test_exp.py | 21 +- tests/db_functions/math/test_floor.py | 25 +- tests/db_functions/math/test_ln.py | 21 +- tests/db_functions/math/test_log.py | 19 +- tests/db_functions/math/test_mod.py | 17 +- tests/db_functions/math/test_pi.py | 1 - tests/db_functions/math/test_power.py | 29 +- tests/db_functions/math/test_radians.py | 25 +- tests/db_functions/math/test_round.py | 59 +- tests/db_functions/math/test_sign.py | 29 +- tests/db_functions/math/test_sin.py | 21 +- tests/db_functions/math/test_sqrt.py | 25 +- tests/db_functions/math/test_tan.py | 21 +- .../migrations/0002_create_test_models.py | 93 +- tests/db_functions/models.py | 4 +- tests/db_functions/tests.py | 72 +- tests/db_functions/text/test_chr.py | 33 +- tests/db_functions/text/test_concat.py | 84 +- tests/db_functions/text/test_left.py | 26 +- tests/db_functions/text/test_length.py | 42 +- tests/db_functions/text/test_lower.py | 36 +- tests/db_functions/text/test_md5.py | 44 +- tests/db_functions/text/test_ord.py | 26 +- tests/db_functions/text/test_pad.py | 54 +- tests/db_functions/text/test_repeat.py | 28 +- tests/db_functions/text/test_replace.py | 86 +- tests/db_functions/text/test_reverse.py | 44 +- tests/db_functions/text/test_right.py | 26 +- tests/db_functions/text/test_sha1.py | 45 +- tests/db_functions/text/test_sha224.py | 53 +- tests/db_functions/text/test_sha256.py | 45 +- tests/db_functions/text/test_sha384.py | 45 +- tests/db_functions/text/test_sha512.py | 59 +- tests/db_functions/text/test_strindex.py | 74 +- tests/db_functions/text/test_substr.py | 39 +- tests/db_functions/text/test_trim.py | 35 +- tests/db_functions/text/test_upper.py | 40 +- tests/db_functions/window/test_validation.py | 20 +- tests/db_typecasts/tests.py | 95 +- tests/db_utils/tests.py | 51 +- tests/dbshell/test_mysql.py | 254 +- tests/dbshell/test_oracle.py | 24 +- tests/dbshell/test_postgresql.py | 191 +- tests/dbshell/test_sqlite.py | 8 +- tests/dbshell/tests.py | 6 +- tests/decorators/tests.py | 156 +- tests/defer/models.py | 5 +- tests/defer/tests.py | 113 +- tests/defer_regress/models.py | 16 +- tests/defer_regress/tests.py | 132 +- tests/delete/models.py | 94 +- tests/delete/tests.py | 178 +- tests/delete_regress/models.py | 21 +- tests/delete_regress/tests.py | 136 +- tests/deprecation/test_csrf_cookie_masked.py | 8 +- tests/deprecation/test_middleware_mixin.py | 26 +- tests/deprecation/test_use_l10n.py | 10 +- tests/deprecation/tests.py | 52 +- tests/dispatch/tests.py | 70 +- tests/distinct_on_fields/models.py | 10 +- tests/distinct_on_fields/tests.py | 117 +- tests/empty_models/test_commands.py | 14 +- tests/expressions/models.py | 20 +- tests/expressions/test_queryset_values.py | 58 +- tests/expressions/tests.py | 1656 +++--- tests/expressions_case/models.py | 42 +- tests/expressions_case/tests.py | 1326 +++-- tests/expressions_window/models.py | 6 +- tests/expressions_window/tests.py | 1752 +++--- tests/extra_regress/models.py | 8 +- tests/extra_regress/tests.py | 320 +- tests/field_deconstruction/tests.py | 209 +- tests/field_defaults/models.py | 2 +- tests/field_subclassing/fields.py | 8 +- tests/field_subclassing/tests.py | 15 +- tests/file_storage/models.py | 36 +- tests/file_storage/test_generate_filename.py | 97 +- tests/file_storage/tests.py | 527 +- tests/file_storage/urls.py | 2 +- tests/file_uploads/models.py | 2 +- tests/file_uploads/tests.py | 873 +-- tests/file_uploads/uploadhandler.py | 26 +- tests/file_uploads/urls.py | 30 +- tests/file_uploads/views.py | 42 +- tests/files/tests.py | 153 +- tests/filtered_relation/models.py | 64 +- tests/filtered_relation/tests.py | 911 +-- tests/fixtures/models.py | 54 +- tests/fixtures/tests.py | 700 ++- tests/fixtures_model_package/models/__init__.py | 6 +- tests/fixtures_model_package/tests.py | 25 +- tests/fixtures_regress/models.py | 77 +- tests/fixtures_regress/tests.py | 521 +- tests/flatpages_tests/absolute_urls.py | 2 +- tests/flatpages_tests/no_slash_urls.py | 2 +- tests/flatpages_tests/settings.py | 18 +- tests/flatpages_tests/test_csrf.py | 77 +- tests/flatpages_tests/test_forms.py | 107 +- tests/flatpages_tests/test_middleware.py | 119 +- tests/flatpages_tests/test_models.py | 25 +- tests/flatpages_tests/test_sitemaps.py | 20 +- tests/flatpages_tests/test_templatetags.py | 72 +- tests/flatpages_tests/test_views.py | 103 +- tests/flatpages_tests/urls.py | 13 +- tests/force_insert_update/tests.py | 14 +- tests/foreign_object/models/__init__.py | 21 +- tests/foreign_object/models/article.py | 36 +- tests/foreign_object/models/customers.py | 20 +- tests/foreign_object/models/empty_join.py | 63 +- tests/foreign_object/models/person.py | 48 +- .../foreign_object/test_agnostic_order_trimjoin.py | 5 +- tests/foreign_object/test_empty_join.py | 26 +- tests/foreign_object/test_forms.py | 10 +- tests/foreign_object/tests.py | 496 +- tests/forms_tests/field_tests/__init__.py | 4 +- tests/forms_tests/field_tests/test_base.py | 13 +- tests/forms_tests/field_tests/test_booleanfield.py | 47 +- tests/forms_tests/field_tests/test_charfield.py | 100 +- tests/forms_tests/field_tests/test_choicefield.py | 73 +- tests/forms_tests/field_tests/test_combofield.py | 37 +- tests/forms_tests/field_tests/test_datefield.py | 183 +- .../forms_tests/field_tests/test_datetimefield.py | 125 +- tests/forms_tests/field_tests/test_decimalfield.py | 193 +- .../forms_tests/field_tests/test_durationfield.py | 37 +- tests/forms_tests/field_tests/test_emailfield.py | 55 +- tests/forms_tests/field_tests/test_filefield.py | 88 +- .../forms_tests/field_tests/test_filepathfield.py | 105 +- tests/forms_tests/field_tests/test_floatfield.py | 85 +- .../field_tests/test_genericipaddressfield.py | 219 +- tests/forms_tests/field_tests/test_imagefield.py | 74 +- tests/forms_tests/field_tests/test_integerfield.py | 112 +- tests/forms_tests/field_tests/test_jsonfield.py | 71 +- .../field_tests/test_multiplechoicefield.py | 75 +- .../field_tests/test_multivaluefield.py | 115 +- .../field_tests/test_nullbooleanfield.py | 52 +- tests/forms_tests/field_tests/test_regexfield.py | 92 +- tests/forms_tests/field_tests/test_slugfield.py | 23 +- .../field_tests/test_splitdatetimefield.py | 75 +- tests/forms_tests/field_tests/test_timefield.py | 31 +- .../field_tests/test_typedchoicefield.py | 62 +- .../field_tests/test_typedmultiplechoicefield.py | 44 +- tests/forms_tests/field_tests/test_urlfield.py | 116 +- tests/forms_tests/field_tests/test_uuidfield.py | 19 +- tests/forms_tests/models.py | 44 +- tests/forms_tests/tests/__init__.py | 6 +- tests/forms_tests/tests/test_deprecation_forms.py | 67 +- tests/forms_tests/tests/test_error_messages.py | 322 +- tests/forms_tests/tests/test_forms.py | 2574 +++++---- tests/forms_tests/tests/test_formsets.py | 1185 ++-- tests/forms_tests/tests/test_i18n.py | 62 +- tests/forms_tests/tests/test_input_formats.py | 304 +- tests/forms_tests/tests/test_media.py | 412 +- tests/forms_tests/tests/test_renderers.py | 24 +- tests/forms_tests/tests/test_utils.py | 215 +- tests/forms_tests/tests/test_validators.py | 122 +- tests/forms_tests/tests/test_widgets.py | 11 +- tests/forms_tests/tests/tests.py | 200 +- tests/forms_tests/urls.py | 4 +- tests/forms_tests/views.py | 8 +- tests/forms_tests/widget_tests/base.py | 22 +- .../forms_tests/widget_tests/test_checkboxinput.py | 89 +- .../widget_tests/test_checkboxselectmultiple.py | 100 +- .../widget_tests/test_clearablefileinput.py | 101 +- tests/forms_tests/widget_tests/test_dateinput.py | 43 +- .../forms_tests/widget_tests/test_datetimeinput.py | 74 +- tests/forms_tests/widget_tests/test_fileinput.py | 23 +- tests/forms_tests/widget_tests/test_hiddeninput.py | 8 +- tests/forms_tests/widget_tests/test_input.py | 20 +- .../widget_tests/test_multiplehiddeninput.py | 44 +- tests/forms_tests/widget_tests/test_multiwidget.py | 203 +- .../widget_tests/test_nullbooleanselect.py | 112 +- tests/forms_tests/widget_tests/test_numberinput.py | 9 +- .../forms_tests/widget_tests/test_passwordinput.py | 23 +- tests/forms_tests/widget_tests/test_radioselect.py | 69 +- tests/forms_tests/widget_tests/test_select.py | 375 +- .../widget_tests/test_selectdatewidget.py | 240 +- .../widget_tests/test_selectmultiple.py | 140 +- .../widget_tests/test_splitdatetimewidget.py | 93 +- .../widget_tests/test_splithiddendatetimewidget.py | 83 +- tests/forms_tests/widget_tests/test_textarea.py | 52 +- tests/forms_tests/widget_tests/test_textinput.py | 79 +- tests/forms_tests/widget_tests/test_timeinput.py | 55 +- tests/forms_tests/widget_tests/test_widget.py | 23 +- tests/from_db_value/models.py | 6 +- tests/from_db_value/tests.py | 12 +- tests/generic_inline_admin/admin.py | 4 +- tests/generic_inline_admin/models.py | 17 +- tests/generic_inline_admin/tests.py | 200 +- tests/generic_inline_admin/urls.py | 2 +- tests/generic_relations/models.py | 24 +- tests/generic_relations/test_forms.py | 198 +- tests/generic_relations/tests.py | 244 +- tests/generic_relations_regress/models.py | 45 +- tests/generic_relations_regress/tests.py | 129 +- tests/generic_views/forms.py | 6 +- tests/generic_views/models.py | 12 +- tests/generic_views/test_base.py | 301 +- tests/generic_views/test_dates.py | 766 +-- tests/generic_views/test_detail.py | 207 +- tests/generic_views/test_edit.py | 401 +- tests/generic_views/test_list.py | 256 +- tests/generic_views/urls.py | 476 +- tests/generic_views/views.py | 120 +- tests/get_earliest_or_latest/models.py | 4 +- tests/get_earliest_or_latest/tests.py | 132 +- tests/get_object_or_404/models.py | 4 +- tests/get_object_or_404/tests.py | 37 +- tests/get_or_create/models.py | 4 +- tests/get_or_create/tests.py | 302 +- tests/gis_tests/distapp/tests.py | 500 +- tests/gis_tests/gdal_tests/test_driver.py | 44 +- tests/gis_tests/gdal_tests/test_ds.py | 162 +- tests/gis_tests/gdal_tests/test_envelope.py | 11 +- tests/gis_tests/gdal_tests/test_geom.py | 275 +- tests/gis_tests/gdal_tests/test_raster.py | 802 +-- tests/gis_tests/gdal_tests/test_srs.py | 160 +- tests/gis_tests/gdal_tests/tests.py | 10 +- tests/gis_tests/geo3d/models.py | 13 +- tests/gis_tests/geo3d/tests.py | 174 +- tests/gis_tests/geoadmin/models.py | 14 +- tests/gis_tests/geoadmin/tests.py | 44 +- tests/gis_tests/geoadmin/urls.py | 2 +- tests/gis_tests/geoadmin_deprecated/models.py | 4 +- tests/gis_tests/geoadmin_deprecated/tests.py | 54 +- tests/gis_tests/geoadmin_deprecated/urls.py | 2 +- tests/gis_tests/geoapp/feeds.py | 21 +- tests/gis_tests/geoapp/models.py | 15 +- tests/gis_tests/geoapp/sitemaps.py | 4 +- tests/gis_tests/geoapp/test_expressions.py | 42 +- tests/gis_tests/geoapp/test_feeds.py | 75 +- tests/gis_tests/geoapp/test_functions.py | 465 +- tests/gis_tests/geoapp/test_indexes.py | 28 +- tests/gis_tests/geoapp/test_regress.py | 56 +- tests/gis_tests/geoapp/test_serializers.py | 65 +- tests/gis_tests/geoapp/test_sitemaps.py | 45 +- tests/gis_tests/geoapp/tests.py | 471 +- tests/gis_tests/geoapp/urls.py | 14 +- tests/gis_tests/geogapp/models.py | 6 +- tests/gis_tests/geogapp/tests.py | 85 +- tests/gis_tests/geos_tests/test_coordseq.py | 3 +- tests/gis_tests/geos_tests/test_geos.py | 460 +- tests/gis_tests/geos_tests/test_geos_mutation.py | 123 +- tests/gis_tests/geos_tests/test_io.py | 115 +- tests/gis_tests/geos_tests/test_mutable_list.py | 196 +- .../migrations/0001_setup_extensions.py | 4 +- .../migrations/0002_create_models.py | 104 +- tests/gis_tests/gis_migrations/test_commands.py | 6 +- tests/gis_tests/gis_migrations/test_operations.py | 195 +- tests/gis_tests/inspectapp/models.py | 2 +- tests/gis_tests/inspectapp/tests.py | 204 +- tests/gis_tests/layermap/models.py | 46 +- tests/gis_tests/layermap/tests.py | 168 +- .../rasterapp/migrations/0001_setup_extensions.py | 4 +- .../rasterapp/migrations/0002_rastermodels.py | 71 +- tests/gis_tests/rasterapp/models.py | 10 +- tests/gis_tests/rasterapp/test_rasterfield.py | 215 +- tests/gis_tests/relatedapp/models.py | 4 +- tests/gis_tests/relatedapp/tests.py | 162 +- tests/gis_tests/test_data.py | 16 +- tests/gis_tests/test_fields.py | 36 +- tests/gis_tests/test_geoforms.py | 371 +- tests/gis_tests/test_geoip2.py | 119 +- tests/gis_tests/test_gis_tests_utils.py | 19 +- tests/gis_tests/test_measure.py | 48 +- tests/gis_tests/test_ptr.py | 7 +- tests/gis_tests/test_spatialrefsys.py | 124 +- tests/gis_tests/tests.py | 28 +- tests/gis_tests/utils.py | 24 +- tests/handlers/test_exception.py | 15 +- tests/handlers/tests.py | 185 +- tests/handlers/tests_custom_error_handlers.py | 17 +- tests/handlers/urls.py | 24 +- tests/handlers/views.py | 4 +- tests/httpwrappers/tests.py | 664 ++- tests/humanize_tests/tests.py | 454 +- tests/i18n/commands/__init__.py | 9 +- tests/i18n/contenttypes/tests.py | 18 +- tests/i18n/forms.py | 2 +- tests/i18n/loading_app/apps.py | 2 +- tests/i18n/models.py | 4 +- tests/i18n/other/locale/fr/formats.py | 2 +- tests/i18n/patterns/tests.py | 376 +- tests/i18n/patterns/urls/default.py | 26 +- tests/i18n/patterns/urls/disabled.py | 4 +- tests/i18n/patterns/urls/included.py | 4 +- tests/i18n/patterns/urls/namespace.py | 10 +- tests/i18n/patterns/urls/path_unused.py | 4 +- tests/i18n/patterns/urls/wrong.py | 5 +- tests/i18n/patterns/urls/wrong_namespace.py | 6 +- tests/i18n/sampleproject/manage.py | 2 +- tests/i18n/sampleproject/update_catalogs.py | 12 +- tests/i18n/test_compilation.py | 214 +- tests/i18n/test_extraction.py | 657 ++- tests/i18n/test_management.py | 30 +- tests/i18n/test_percents.py | 103 +- tests/i18n/tests.py | 1921 ++++--- tests/i18n/unchanged/__init__.py | 4 +- tests/i18n/urls.py | 4 +- tests/i18n/urls_default_unprefixed.py | 6 +- tests/i18n/utils.py | 19 +- tests/indexes/models.py | 17 +- tests/indexes/tests.py | 484 +- tests/inline_formsets/models.py | 6 +- tests/inline_formsets/tests.py | 152 +- tests/inspectdb/models.py | 48 +- tests/inspectdb/tests.py | 401 +- tests/introspection/models.py | 33 +- tests/introspection/tests.py | 315 +- .../invalid_models_tests/test_backend_specific.py | 19 +- tests/invalid_models_tests/test_custom_fields.py | 5 +- .../invalid_models_tests/test_deprecated_fields.py | 78 +- tests/invalid_models_tests/test_models.py | 2446 ++++---- tests/invalid_models_tests/test_ordinary_fields.py | 1085 ++-- tests/invalid_models_tests/test_relative_fields.py | 2156 +++---- tests/known_related_objects/tests.py | 51 +- tests/logging_tests/logconfig.py | 2 +- tests/logging_tests/tests.py | 355 +- tests/logging_tests/urls.py | 18 +- tests/logging_tests/urls_i18n.py | 2 +- tests/logging_tests/views.py | 27 +- tests/lookup/models.py | 26 +- tests/lookup/test_decimalfield.py | 10 +- tests/lookup/test_lookups.py | 14 +- tests/lookup/test_timefield.py | 7 +- tests/lookup/tests.py | 1089 ++-- tests/m2m_and_m2o/models.py | 8 +- tests/m2m_and_m2o/tests.py | 38 +- tests/m2m_intermediary/tests.py | 12 +- tests/m2m_multiple/models.py | 12 +- tests/m2m_multiple/tests.py | 51 +- tests/m2m_recursive/models.py | 8 +- tests/m2m_recursive/tests.py | 46 +- tests/m2m_regress/models.py | 15 +- tests/m2m_regress/tests.py | 54 +- tests/m2m_signals/models.py | 12 +- tests/m2m_signals/tests.py | 699 ++- tests/m2m_through/models.py | 64 +- tests/m2m_through/tests.py | 357 +- tests/m2m_through_regress/models.py | 28 +- tests/m2m_through_regress/test_multitable.py | 34 +- tests/m2m_through_regress/tests.py | 56 +- tests/m2o_recursive/models.py | 12 +- tests/m2o_recursive/tests.py | 20 +- tests/mail/custombackend.py | 1 - tests/mail/test_sendtestemail.py | 83 +- tests/mail/tests.py | 1434 +++-- tests/managers_regress/models.py | 18 +- tests/managers_regress/tests.py | 86 +- tests/many_to_many/models.py | 18 +- tests/many_to_many/tests.py | 148 +- tests/many_to_one/models.py | 26 +- tests/many_to_one/tests.py | 379 +- tests/many_to_one_null/models.py | 6 +- tests/many_to_one_null/tests.py | 26 +- tests/max_lengths/tests.py | 24 +- tests/messages_tests/base.py | 221 +- tests/messages_tests/test_api.py | 15 +- tests/messages_tests/test_cookie.py | 71 +- tests/messages_tests/test_fallback.py | 19 +- tests/messages_tests/test_middleware.py | 5 +- tests/messages_tests/test_mixins.py | 13 +- tests/messages_tests/test_session.py | 14 +- tests/messages_tests/tests.py | 18 +- tests/messages_tests/urls.py | 39 +- tests/middleware/cond_get_urls.py | 2 +- tests/middleware/extra_urls.py | 6 +- tests/middleware/test_security.py | 88 +- tests/middleware/tests.py | 537 +- tests/middleware/urls.py | 12 +- tests/middleware/views.py | 2 +- tests/middleware_exceptions/middleware.py | 35 +- tests/middleware_exceptions/tests.py | 376 +- tests/middleware_exceptions/urls.py | 12 +- tests/middleware_exceptions/views.py | 18 +- tests/migrate_signals/tests.py | 90 +- .../migrations/0001_initial.py | 20 +- .../deprecated_field_migrations/0001_initial.py | 17 +- .../0002_remove_ipaddressfield_ip.py | 6 +- .../alter_fk/author_app/migrations/0001_initial.py | 14 +- .../author_app/migrations/0002_alter_id.py | 8 +- .../alter_fk/book_app/migrations/0001_initial.py | 15 +- .../migrations/0001_initial.py | 2 +- .../migrations/0002_second.py | 2 +- .../lookuperror_a/migrations/0001_initial.py | 15 +- .../lookuperror_a/migrations/0002_a2.py | 14 +- .../lookuperror_a/migrations/0003_a3.py | 22 +- .../lookuperror_a/migrations/0004_a4.py | 14 +- .../migrations_test_apps/lookuperror_a/models.py | 4 +- .../lookuperror_b/migrations/0001_initial.py | 15 +- .../lookuperror_b/migrations/0002_b2.py | 18 +- .../lookuperror_b/migrations/0003_b3.py | 14 +- .../migrations_test_apps/lookuperror_b/models.py | 2 +- .../lookuperror_c/migrations/0001_initial.py | 15 +- .../lookuperror_c/migrations/0002_c2.py | 18 +- .../lookuperror_c/migrations/0003_c3.py | 14 +- .../migrations_test_apps/lookuperror_c/models.py | 2 +- .../migrated_app/migrations/0001_initial.py | 5 +- .../migrations/0001_initial.py | 2 - .../mutate_state_a/migrations/0001_initial.py | 29 +- .../mutate_state_b/migrations/0001_initial.py | 30 +- .../mutate_state_b/migrations/0002_add_field.py | 19 +- .../unmigrated_app_simple/models.py | 1 + .../migrations/0001_initial.py | 5 +- .../migrations/0002_conflicting_second.py | 2 - .../migrations/0002_second.py | 7 +- tests/migrations/models.py | 8 +- tests/migrations/routers.py | 8 +- .../0001_initial.py | 33 +- .../0002_initial.py | 6 +- tests/migrations/test_auto_now_add/0001_initial.py | 14 +- tests/migrations/test_autodetector.py | 4783 ++++++++++------ tests/migrations/test_base.py | 304 +- tests/migrations/test_commands.py | 1775 +++--- tests/migrations/test_deprecated_fields.py | 5 +- tests/migrations/test_exceptions.py | 7 +- tests/migrations/test_executor.py | 486 +- .../fake_initial/0001_initial.py | 22 +- .../initial/0001_initial.py | 19 +- tests/migrations/test_graph.py | 151 +- tests/migrations/test_loader.py | 358 +- tests/migrations/test_migrations/0001_initial.py | 8 +- tests/migrations/test_migrations/0002_second.py | 12 +- .../0001_initial.py | 6 +- .../0002_second.py | 2 +- .../test_migrations_clashing_prefix/ab.py | 2 +- .../test_migrations_conflict/0001_initial.py | 5 +- .../0002_conflicting_second.py | 2 - .../test_migrations_conflict/0002_second.py | 12 +- .../0001_initial.py | 4 +- ..._conflicting_second_migration_with_long_name.py | 6 +- .../0002_second.py | 6 +- .../test_migrations_custom_user/0001_initial.py | 12 +- .../0001_initial.py | 4 +- .../0002_second.py | 5 +- tests/migrations/test_migrations_first/second.py | 12 +- tests/migrations/test_migrations_first/thefirst.py | 5 +- .../0001_not_initial.py | 4 +- .../test_migrations_manual_porting/0001_initial.py | 6 +- .../test_migrations_manual_porting/0002_second.py | 2 +- .../test_migrations_no_ancestor/0001_initial.py | 5 +- .../0002_conflicting_second.py | 15 +- .../test_migrations_no_ancestor/0002_second.py | 12 +- .../test_migrations_no_changes/0001_initial.py | 5 +- .../test_migrations_no_changes/0002_second.py | 12 +- .../test_migrations_no_changes/0003_third.py | 30 +- .../test_migrations_no_default/0001_initial.py | 20 +- .../test_migrations_non_atomic/0001_initial.py | 13 +- tests/migrations/test_migrations_order/0001.py | 3 +- .../test_migrations_plan/0001_initial.py | 8 +- .../migrations/test_migrations_plan/0002_second.py | 12 +- .../migrations/test_migrations_plan/0003_third.py | 11 +- .../migrations/test_migrations_plan/0004_fourth.py | 4 +- .../migrations/test_migrations_plan/0005_fifth.py | 2 +- .../test_migrations_run_before/0001_initial.py | 2 - .../test_migrations_run_before/0002_second.py | 7 +- .../test_migrations_run_before/0003_third.py | 2 - .../test_migrations_squashed/0001_initial.py | 5 +- .../test_migrations_squashed/0001_squashed_0002.py | 8 +- .../test_migrations_squashed/0002_second.py | 12 +- .../test_migrations_squashed_complex/1_auto.py | 4 +- .../test_migrations_squashed_complex/2_auto.py | 4 +- .../test_migrations_squashed_complex/3_auto.py | 4 +- .../3_squashed_5.py | 4 +- .../test_migrations_squashed_complex/4_auto.py | 4 +- .../test_migrations_squashed_complex/5_auto.py | 4 +- .../test_migrations_squashed_complex/6_auto.py | 4 +- .../test_migrations_squashed_complex/7_auto.py | 4 +- .../app1/1_auto.py | 4 +- .../app1/2_auto.py | 4 +- .../app1/2_squashed_3.py | 4 +- .../app1/3_auto.py | 4 +- .../app1/4_auto.py | 4 +- .../app2/1_auto.py | 4 +- .../app2/1_squashed_2.py | 4 +- .../app2/2_auto.py | 4 +- .../test_migrations_squashed_erroneous/1_auto.py | 4 +- .../test_migrations_squashed_erroneous/2_auto.py | 4 +- .../3_squashed_5.py | 4 +- .../test_migrations_squashed_erroneous/6_auto.py | 4 +- .../test_migrations_squashed_erroneous/7_auto.py | 4 +- .../0001_squashed_0002.py | 5 +- .../test_migrations_unmigdep/0001_initial.py | 2 - tests/migrations/test_multidb.py | 34 +- tests/migrations/test_operations.py | 3275 +++++++---- tests/migrations/test_optimizer.py | 621 +- tests/migrations/test_questioner.py | 54 +- tests/migrations/test_state.py | 1389 +++-- tests/migrations/test_writer.py | 567 +- .../migrations2/test_migrations_2/0001_initial.py | 2 - .../test_migrations_2_first/0001_initial.py | 2 - .../test_migrations_2_first/0002_second.py | 2 - .../test_migrations_2_no_deps/0001_initial.py | 2 - tests/model_enums/tests.py | 247 +- tests/model_fields/models.py | 142 +- tests/model_fields/test_autofield.py | 5 +- tests/model_fields/test_binaryfield.py | 24 +- tests/model_fields/test_booleanfield.py | 17 +- tests/model_fields/test_charfield.py | 42 +- tests/model_fields/test_datetimefield.py | 36 +- tests/model_fields/test_decimalfield.py | 61 +- tests/model_fields/test_durationfield.py | 19 +- tests/model_fields/test_field_flags.py | 66 +- tests/model_fields/test_filefield.py | 82 +- tests/model_fields/test_floatfield.py | 9 +- tests/model_fields/test_foreignkey.py | 64 +- tests/model_fields/test_genericipaddressfield.py | 15 +- tests/model_fields/test_imagefield.py | 120 +- tests/model_fields/test_integerfield.py | 71 +- tests/model_fields/test_jsonfield.py | 683 ++- tests/model_fields/test_manytomanyfield.py | 42 +- tests/model_fields/test_promises.py | 69 +- tests/model_fields/test_slugfield.py | 9 +- tests/model_fields/test_textfield.py | 13 +- tests/model_fields/test_uuid.py | 135 +- tests/model_fields/tests.py | 197 +- tests/model_forms/models.py | 147 +- tests/model_forms/test_modelchoicefield.py | 283 +- tests/model_forms/test_uuid.py | 10 +- tests/model_forms/tests.py | 1904 ++++--- tests/model_formsets/models.py | 32 +- tests/model_formsets/test_uuid.py | 59 +- tests/model_formsets/tests.py | 1590 +++--- tests/model_formsets_regress/models.py | 5 +- tests/model_formsets_regress/tests.py | 370 +- tests/model_indexes/models.py | 18 +- tests/model_indexes/tests.py | 238 +- tests/model_inheritance/models.py | 33 +- .../model_inheritance/test_abstract_inheritance.py | 152 +- tests/model_inheritance/tests.py | 240 +- tests/model_inheritance_regress/models.py | 20 +- tests/model_inheritance_regress/tests.py | 365 +- tests/model_meta/models.py | 112 +- tests/model_meta/results.py | 1441 +++-- tests/model_meta/tests.py | 174 +- tests/model_options/apps.py | 16 +- tests/model_options/models/tablespaces.py | 30 +- tests/model_options/test_default_pk.py | 50 +- tests/model_options/test_default_related_name.py | 9 +- tests/model_options/test_tablespaces.py | 75 +- tests/model_package/models/__init__.py | 2 +- tests/model_package/tests.py | 22 +- tests/model_regress/models.py | 12 +- tests/model_regress/test_pickle.py | 9 +- tests/model_regress/test_state.py | 5 +- tests/model_regress/tests.py | 88 +- tests/model_utils/tests.py | 6 +- tests/modeladmin/models.py | 28 +- tests/modeladmin/test_actions.py | 75 +- tests/modeladmin/test_checks.py | 724 +-- tests/modeladmin/tests.py | 411 +- tests/multiple_database/models.py | 18 +- tests/multiple_database/routers.py | 25 +- tests/multiple_database/tests.py | 1717 +++--- tests/mutually_referential/models.py | 4 +- tests/mutually_referential/tests.py | 7 +- tests/nested_foreign_keys/tests.py | 248 +- tests/no_models/tests.py | 3 +- tests/null_fk/models.py | 5 +- tests/null_fk/tests.py | 49 +- tests/null_fk_ordering/models.py | 4 +- tests/null_fk_ordering/tests.py | 35 +- tests/null_queries/models.py | 1 + tests/null_queries/tests.py | 21 +- tests/one_to_one/models.py | 8 +- tests/one_to_one/tests.py | 134 +- tests/or_lookups/models.py | 2 +- tests/or_lookups/tests.py | 198 +- tests/order_with_respect_to/base_tests.py | 41 +- tests/order_with_respect_to/models.py | 12 +- tests/order_with_respect_to/tests.py | 13 +- tests/ordering/models.py | 22 +- tests/ordering/tests.py | 305 +- tests/pagination/custom.py | 2 - tests/pagination/models.py | 2 +- tests/pagination/tests.py | 107 +- tests/postgres_tests/__init__.py | 8 +- .../array_default_migrations/0001_initial.py | 25 +- .../0002_integerarraymodel_field_2.py | 10 +- .../array_index_migrations/0001_initial.py | 36 +- tests/postgres_tests/fields.py | 28 +- tests/postgres_tests/integration_settings.py | 4 +- .../migrations/0001_setup_extensions.py | 15 +- .../migrations/0002_create_test_models.py | 542 +- tests/postgres_tests/models.py | 40 +- tests/postgres_tests/test_aggregates.py | 769 +-- tests/postgres_tests/test_apps.py | 49 +- tests/postgres_tests/test_array.py | 802 +-- tests/postgres_tests/test_bulk_update.py | 37 +- tests/postgres_tests/test_citext.py | 59 +- tests/postgres_tests/test_constraints.py | 802 +-- tests/postgres_tests/test_functions.py | 2 - tests/postgres_tests/test_hstore.py | 315 +- tests/postgres_tests/test_indexes.py | 526 +- tests/postgres_tests/test_integration.py | 17 +- tests/postgres_tests/test_introspection.py | 16 +- tests/postgres_tests/test_operations.py | 434 +- tests/postgres_tests/test_ranges.py | 534 +- tests/postgres_tests/test_search.py | 594 +- tests/postgres_tests/test_signals.py | 5 +- tests/postgres_tests/test_trigram.py | 71 +- tests/postgres_tests/test_unaccent.py | 35 +- tests/prefetch_related/models.py | 139 +- .../test_prefetch_related_objects.py | 76 +- tests/prefetch_related/test_uuid.py | 76 +- tests/prefetch_related/tests.py | 1305 +++-- tests/project_template/test_settings.py | 33 +- tests/project_template/urls.py | 2 +- tests/properties/models.py | 2 +- tests/properties/tests.py | 13 +- tests/proxy_model_inheritance/models.py | 1 - tests/proxy_model_inheritance/tests.py | 11 +- tests/proxy_models/admin.py | 2 +- tests/proxy_models/models.py | 33 +- tests/proxy_models/tests.py | 239 +- tests/proxy_models/urls.py | 2 +- tests/queries/models.py | 152 +- tests/queries/test_bulk_update.py | 210 +- tests/queries/test_contains.py | 10 +- tests/queries/test_db_returning.py | 24 +- tests/queries/test_explain.py | 106 +- tests/queries/test_iterator.py | 18 +- tests/queries/test_q.py | 77 +- tests/queries/test_qs_combinators.py | 386 +- tests/queries/test_query.py | 46 +- tests/queries/test_sqlcompiler.py | 2 +- tests/queries/tests.py | 2633 +++++---- tests/queryset_pickle/models.py | 8 +- tests/queryset_pickle/tests.py | 148 +- tests/raw_query/models.py | 9 +- tests/raw_query/tests.py | 189 +- tests/redirects_tests/tests.py | 76 +- tests/redirects_tests/urls.py | 2 +- tests/requests/test_accept_header.py | 84 +- tests/requests/test_data_upload_settings.py | 187 +- tests/requests/tests.py | 1054 ++-- tests/reserved_names/models.py | 4 +- tests/reserved_names/tests.py | 61 +- tests/resolve_url/models.py | 2 +- tests/resolve_url/tests.py | 28 +- tests/resolve_url/urls.py | 2 +- tests/responses/test_cookie.py | 108 +- tests/responses/test_fileresponse.py | 158 +- tests/responses/tests.py | 78 +- tests/reverse_lookup/models.py | 4 +- tests/reverse_lookup/tests.py | 21 +- tests/runtests.py | 478 +- tests/save_delete_hooks/tests.py | 31 +- tests/schema/fields.py | 63 +- tests/schema/models.py | 8 +- tests/schema/test_logging.py | 7 +- tests/schema/tests.py | 2190 ++++--- tests/select_for_update/models.py | 6 +- tests/select_for_update/tests.py | 375 +- tests/select_related/models.py | 15 +- tests/select_related/tests.py | 208 +- tests/select_related_onetoone/models.py | 8 +- tests/select_related_onetoone/tests.py | 191 +- tests/select_related_regress/models.py | 12 +- tests/select_related_regress/tests.py | 187 +- tests/serializers/models/base.py | 26 +- tests/serializers/models/data.py | 22 +- tests/serializers/models/multi_table.py | 2 +- tests/serializers/models/natural.py | 14 +- tests/serializers/test_data.py | 216 +- tests/serializers/test_deserializedobject.py | 7 +- tests/serializers/test_json.py | 52 +- tests/serializers/test_jsonl.py | 45 +- tests/serializers/test_natural.py | 162 +- tests/serializers/test_xml.py | 8 +- tests/serializers/test_yaml.py | 31 +- tests/serializers/tests.py | 189 +- tests/servers/test_basehttp.py | 66 +- tests/servers/tests.py | 173 +- tests/servers/urls.py | 18 +- tests/servers/views.py | 24 +- tests/sessions_tests/models.py | 4 +- tests/sessions_tests/no_clear_expired.py | 1 + tests/sessions_tests/tests.py | 308 +- tests/settings_tests/tests.py | 447 +- tests/shell/tests.py | 60 +- tests/shortcuts/tests.py | 37 +- tests/shortcuts/urls.py | 10 +- tests/shortcuts/views.py | 60 +- tests/signals/tests.py | 294 +- tests/signed_cookies_tests/tests.py | 57 +- tests/signing/tests.py | 161 +- tests/sitemaps_tests/base.py | 16 +- tests/sitemaps_tests/models.py | 4 +- tests/sitemaps_tests/test_generic.py | 57 +- tests/sitemaps_tests/test_http.py | 286 +- tests/sitemaps_tests/test_https.py | 34 +- tests/sitemaps_tests/test_management.py | 11 +- tests/sitemaps_tests/test_utils.py | 40 +- tests/sitemaps_tests/urls/http.py | 322 +- tests/sitemaps_tests/urls/https.py | 14 +- tests/sitemaps_tests/urls/index_only.py | 7 +- tests/sitemaps_tests/urls/sitemap_only.py | 6 +- tests/sites_framework/migrations/0001_initial.py | 59 +- tests/sites_framework/tests.py | 20 +- tests/sites_tests/tests.py | 123 +- tests/staticfiles_tests/apps/staticfiles_config.py | 2 +- tests/staticfiles_tests/cases.py | 36 +- tests/staticfiles_tests/settings.py | 36 +- tests/staticfiles_tests/storage.py | 16 +- tests/staticfiles_tests/test_checks.py | 125 +- tests/staticfiles_tests/test_finders.py | 53 +- tests/staticfiles_tests/test_forms.py | 20 +- tests/staticfiles_tests/test_handlers.py | 4 +- tests/staticfiles_tests/test_liveserver.py | 24 +- tests/staticfiles_tests/test_management.py | 269 +- tests/staticfiles_tests/test_storage.py | 295 +- tests/staticfiles_tests/test_templatetags.py | 13 +- tests/staticfiles_tests/test_utils.py | 3 +- tests/staticfiles_tests/test_views.py | 8 +- tests/staticfiles_tests/urls/default.py | 2 +- tests/str/tests.py | 18 +- tests/string_lookup/models.py | 4 +- tests/string_lookup/tests.py | 26 +- tests/swappable_models/models.py | 2 +- tests/swappable_models/tests.py | 37 +- tests/syndication_tests/feeds.py | 91 +- tests/syndication_tests/models.py | 4 +- tests/syndication_tests/tests.py | 619 +- tests/syndication_tests/urls.py | 46 +- tests/template_backends/test_django.py | 212 +- tests/template_backends/test_dummy.py | 59 +- tests/template_backends/test_jinja2.py | 146 +- tests/template_backends/test_utils.py | 36 +- tests/template_loader/tests.py | 130 +- tests/template_tests/alternate_urls.py | 5 +- tests/template_tests/filter_tests/test_add.py | 63 +- .../template_tests/filter_tests/test_addslashes.py | 26 +- .../template_tests/filter_tests/test_autoescape.py | 40 +- tests/template_tests/filter_tests/test_capfirst.py | 24 +- tests/template_tests/filter_tests/test_center.py | 22 +- tests/template_tests/filter_tests/test_chaining.py | 131 +- tests/template_tests/filter_tests/test_cut.py | 60 +- tests/template_tests/filter_tests/test_date.py | 75 +- tests/template_tests/filter_tests/test_default.py | 36 +- .../filter_tests/test_default_if_none.py | 7 +- tests/template_tests/filter_tests/test_dictsort.py | 109 +- .../filter_tests/test_dictsortreversed.py | 53 +- .../filter_tests/test_divisibleby.py | 1 - tests/template_tests/filter_tests/test_escape.py | 33 +- tests/template_tests/filter_tests/test_escapejs.py | 60 +- .../filter_tests/test_filesizeformat.py | 73 +- tests/template_tests/filter_tests/test_first.py | 22 +- .../filter_tests/test_floatformat.py | 158 +- .../filter_tests/test_force_escape.py | 57 +- .../template_tests/filter_tests/test_get_digit.py | 3 +- .../template_tests/filter_tests/test_iriencode.py | 41 +- tests/template_tests/filter_tests/test_join.py | 72 +- .../filter_tests/test_json_script.py | 12 +- tests/template_tests/filter_tests/test_last.py | 21 +- tests/template_tests/filter_tests/test_length.py | 52 +- .../template_tests/filter_tests/test_length_is.py | 110 +- .../template_tests/filter_tests/test_linebreaks.py | 43 +- .../filter_tests/test_linebreaksbr.py | 33 +- .../filter_tests/test_linenumbers.py | 41 +- tests/template_tests/filter_tests/test_ljust.py | 26 +- tests/template_tests/filter_tests/test_lower.py | 24 +- .../template_tests/filter_tests/test_make_list.py | 29 +- .../filter_tests/test_phone2numeric.py | 33 +- .../template_tests/filter_tests/test_pluralize.py | 60 +- tests/template_tests/filter_tests/test_random.py | 17 +- tests/template_tests/filter_tests/test_rjust.py | 24 +- tests/template_tests/filter_tests/test_safe.py | 13 +- tests/template_tests/filter_tests/test_safeseq.py | 17 +- tests/template_tests/filter_tests/test_slice.py | 40 +- tests/template_tests/filter_tests/test_slugify.py | 39 +- .../filter_tests/test_stringformat.py | 48 +- .../template_tests/filter_tests/test_striptags.py | 38 +- tests/template_tests/filter_tests/test_time.py | 61 +- .../template_tests/filter_tests/test_timesince.py | 143 +- .../template_tests/filter_tests/test_timeuntil.py | 133 +- tests/template_tests/filter_tests/test_title.py | 20 +- .../filter_tests/test_truncatechars.py | 23 +- .../filter_tests/test_truncatechars_html.py | 30 +- .../filter_tests/test_truncatewords.py | 38 +- .../filter_tests/test_truncatewords_html.py | 36 +- .../filter_tests/test_unordered_list.py | 132 +- tests/template_tests/filter_tests/test_upper.py | 27 +- .../template_tests/filter_tests/test_urlencode.py | 18 +- tests/template_tests/filter_tests/test_urlize.py | 226 +- .../filter_tests/test_urlizetrunc.py | 45 +- .../template_tests/filter_tests/test_wordcount.py | 28 +- tests/template_tests/filter_tests/test_wordwrap.py | 58 +- tests/template_tests/filter_tests/test_yesno.py | 29 +- .../template_tests/filter_tests/timezone_utils.py | 7 +- tests/template_tests/syntax_tests/i18n/base.py | 2 +- .../syntax_tests/i18n/test_blocktranslate.py | 805 ++- .../syntax_tests/i18n/test_filters.py | 76 +- .../i18n/test_get_available_languages.py | 20 +- .../syntax_tests/i18n/test_get_current_language.py | 6 +- .../i18n/test_get_current_language_bidi.py | 6 +- .../syntax_tests/i18n/test_get_language_info.py | 54 +- .../i18n/test_get_language_info_list.py | 70 +- .../syntax_tests/i18n/test_language.py | 10 +- .../syntax_tests/i18n/test_translate.py | 272 +- .../syntax_tests/i18n/test_underscore_syntax.py | 98 +- .../template_tests/syntax_tests/test_autoescape.py | 155 +- tests/template_tests/syntax_tests/test_basic.py | 253 +- tests/template_tests/syntax_tests/test_builtins.py | 19 +- tests/template_tests/syntax_tests/test_cache.py | 211 +- tests/template_tests/syntax_tests/test_comment.py | 111 +- tests/template_tests/syntax_tests/test_cycle.py | 267 +- tests/template_tests/syntax_tests/test_debug.py | 47 +- .../template_tests/syntax_tests/test_exceptions.py | 29 +- tests/template_tests/syntax_tests/test_extends.py | 294 +- .../syntax_tests/test_filter_syntax.py | 139 +- .../template_tests/syntax_tests/test_filter_tag.py | 41 +- tests/template_tests/syntax_tests/test_firstof.py | 103 +- tests/template_tests/syntax_tests/test_for.py | 350 +- tests/template_tests/syntax_tests/test_if.py | 761 +-- .../template_tests/syntax_tests/test_if_changed.py | 348 +- tests/template_tests/syntax_tests/test_include.py | 307 +- .../syntax_tests/test_invalid_string.py | 64 +- .../template_tests/syntax_tests/test_list_index.py | 55 +- tests/template_tests/syntax_tests/test_load.py | 76 +- tests/template_tests/syntax_tests/test_lorem.py | 33 +- .../template_tests/syntax_tests/test_multiline.py | 5 +- .../syntax_tests/test_named_endblock.py | 75 +- tests/template_tests/syntax_tests/test_now.py | 97 +- tests/template_tests/syntax_tests/test_numpy.py | 19 +- tests/template_tests/syntax_tests/test_regroup.py | 197 +- .../template_tests/syntax_tests/test_resetcycle.py | 169 +- tests/template_tests/syntax_tests/test_setup.py | 23 +- .../template_tests/syntax_tests/test_simple_tag.py | 18 +- .../template_tests/syntax_tests/test_spaceless.py | 49 +- tests/template_tests/syntax_tests/test_static.py | 95 +- .../syntax_tests/test_template_tag.py | 71 +- tests/template_tests/syntax_tests/test_url.py | 296 +- tests/template_tests/syntax_tests/test_verbatim.py | 55 +- .../syntax_tests/test_width_ratio.py | 160 +- tests/template_tests/syntax_tests/test_with.py | 62 +- tests/template_tests/templatetags/custom.py | 46 +- tests/template_tests/templatetags/inclusion.py | 177 +- tests/template_tests/templatetags/tag_27584.py | 4 +- tests/template_tests/templatetags/testtags.py | 4 +- tests/template_tests/test_autoreloader.py | 100 +- tests/template_tests/test_base.py | 44 +- tests/template_tests/test_callables.py | 36 +- tests/template_tests/test_context.py | 220 +- tests/template_tests/test_custom.py | 498 +- tests/template_tests/test_engine.py | 103 +- tests/template_tests/test_extends.py | 159 +- tests/template_tests/test_extends_relative.py | 65 +- tests/template_tests/test_library.py | 109 +- tests/template_tests/test_loaders.py | 177 +- tests/template_tests/test_logging.py | 22 +- tests/template_tests/test_nodelist.py | 55 +- tests/template_tests/test_origin.py | 14 +- tests/template_tests/test_parser.py | 57 +- tests/template_tests/test_response.py | 296 +- tests/template_tests/test_smartif.py | 29 +- tests/template_tests/tests.py | 57 +- tests/template_tests/urls.py | 27 +- tests/template_tests/utils.py | 31 +- tests/template_tests/views.py | 4 +- .../test_conditional_content_removal.py | 37 +- tests/test_client/test_fakepayload.py | 2 +- tests/test_client/tests.py | 771 +-- tests/test_client/urls.py | 110 +- tests/test_client/urls_middleware_urlconf.py | 2 +- tests/test_client/views.py | 261 +- tests/test_client_regress/auth_backends.py | 1 - tests/test_client_regress/context_processors.py | 2 +- tests/test_client_regress/models.py | 6 +- tests/test_client_regress/session.py | 1 + tests/test_client_regress/tests.py | 1269 +++-- tests/test_client_regress/urls.py | 97 +- tests/test_client_regress/views.py | 85 +- tests/test_exceptions/test_validation_error.py | 394 +- tests/test_runner/models.py | 4 +- tests/test_runner/runner.py | 23 +- tests/test_runner/test_debug_sql.py | 79 +- tests/test_runner/test_discover_runner.py | 557 +- tests/test_runner/test_parallel.py | 27 +- tests/test_runner/test_shuffler.py | 59 +- tests/test_runner/tests.py | 734 ++- tests/test_runner_apps/buffer/tests_buffer.py | 8 +- tests/test_runner_apps/databases/tests.py | 8 +- tests/test_runner_apps/failures/tests_failures.py | 2 +- tests/test_runner_apps/sample/doctests.py | 1 + tests/test_runner_apps/sample/pattern_tests.py | 1 - tests/test_runner_apps/sample/tests/tests.py | 1 - tests/test_runner_apps/sample/tests_sample.py | 5 +- tests/test_runner_apps/simple/tests.py | 9 +- tests/test_runner_apps/tagged/tests.py | 7 +- tests/test_runner_apps/tagged/tests_inheritance.py | 10 +- tests/test_sqlite.py | 14 +- tests/test_utils/models.py | 6 +- tests/test_utils/test_serializemixin.py | 1 + tests/test_utils/test_simpletestcase.py | 48 +- tests/test_utils/test_testcase.py | 37 +- tests/test_utils/test_transactiontestcase.py | 27 +- tests/test_utils/tests.py | 1091 ++-- tests/test_utils/urls.py | 6 +- tests/timezones/admin.py | 6 +- tests/timezones/forms.py | 6 +- tests/timezones/models.py | 2 +- tests/timezones/tests.py | 846 +-- tests/timezones/urls.py | 2 +- tests/transaction_hooks/tests.py | 13 +- tests/transactions/models.py | 2 +- tests/transactions/tests.py | 94 +- tests/unmanaged_models/models.py | 16 +- tests/unmanaged_models/tests.py | 12 +- tests/update/models.py | 4 +- tests/update/tests.py | 130 +- tests/update_only_fields/models.py | 11 +- tests/update_only_fields/tests.py | 194 +- tests/urlpatterns/converter_urls.py | 4 +- tests/urlpatterns/converters.py | 6 +- tests/urlpatterns/included_urls.py | 4 +- tests/urlpatterns/more_urls.py | 2 +- tests/urlpatterns/path_base64_urls.py | 20 +- tests/urlpatterns/path_dynamic_urls.py | 4 +- tests/urlpatterns/path_same_name_urls.py | 32 +- tests/urlpatterns/path_urls.py | 36 +- tests/urlpatterns/test_resolvers.py | 12 +- tests/urlpatterns/tests.py | 317 +- tests/urlpatterns_reverse/erroneous_urls.py | 2 +- tests/urlpatterns_reverse/extra_urls.py | 8 +- tests/urlpatterns_reverse/included_app_urls.py | 29 +- tests/urlpatterns_reverse/included_named_urls.py | 8 +- tests/urlpatterns_reverse/included_named_urls2.py | 6 +- .../urlpatterns_reverse/included_namespace_urls.py | 48 +- .../urlpatterns_reverse/included_no_kwargs_urls.py | 2 +- tests/urlpatterns_reverse/included_urls.py | 6 +- tests/urlpatterns_reverse/included_urls2.py | 4 +- tests/urlpatterns_reverse/method_view_urls.py | 4 +- tests/urlpatterns_reverse/middleware.py | 10 +- tests/urlpatterns_reverse/named_urls.py | 8 +- tests/urlpatterns_reverse/named_urls_conflict.py | 24 +- tests/urlpatterns_reverse/namespace_urls.py | 117 +- tests/urlpatterns_reverse/nested_urls.py | 15 +- tests/urlpatterns_reverse/reverse_lazy_urls.py | 8 +- .../test_localeregexdescriptor.py | 36 +- tests/urlpatterns_reverse/tests.py | 1423 +++-- tests/urlpatterns_reverse/urlconf_inner.py | 8 +- tests/urlpatterns_reverse/urlconf_outer.py | 4 +- tests/urlpatterns_reverse/urls.py | 183 +- tests/urlpatterns_reverse/urls_error_handlers.py | 6 +- tests/urlpatterns_reverse/urls_without_handlers.py | 4 +- tests/urlpatterns_reverse/utils.py | 10 +- tests/urlpatterns_reverse/views.py | 15 +- tests/urlpatterns_reverse/views_broken.py | 2 +- .../management/commands/common_args.py | 6 +- tests/user_commands/management/commands/dance.py | 18 +- tests/user_commands/management/commands/hal.py | 13 +- .../commands/mutually_exclusive_required.py | 19 +- .../mutually_exclusive_required_with_same_dest.py | 6 +- .../management/commands/no_translations.py | 1 - .../management/commands/outputwrapper.py | 4 +- .../commands/required_constant_option.py | 14 +- .../management/commands/required_list_option.py | 4 +- .../management/commands/required_option.py | 7 +- .../management/commands/reverse_url.py | 3 +- .../management/commands/set_option.py | 5 +- .../user_commands/management/commands/subparser.py | 7 +- .../management/commands/subparser_dest.py | 8 +- .../management/commands/subparser_required.py | 12 +- .../management/commands/transaction.py | 4 +- tests/user_commands/tests.py | 365 +- tests/user_commands/urls.py | 2 +- tests/utils_tests/test_archive.py | 52 +- tests/utils_tests/test_autoreload.py | 474 +- tests/utils_tests/test_baseconv.py | 57 +- tests/utils_tests/test_connection.py | 2 +- tests/utils_tests/test_crypto.py | 84 +- tests/utils_tests/test_datastructures.py | 271 +- tests/utils_tests/test_dateformat.py | 240 +- tests/utils_tests/test_dateparse.py | 230 +- tests/utils_tests/test_datetime_safe.py | 52 +- tests/utils_tests/test_deconstruct.py | 60 +- tests/utils_tests/test_decorators.py | 33 +- tests/utils_tests/test_duration.py | 33 +- tests/utils_tests/test_encoding.py | 154 +- tests/utils_tests/test_feedgenerator.py | 74 +- tests/utils_tests/test_functional.py | 57 +- tests/utils_tests/test_hashable.py | 18 +- tests/utils_tests/test_html.py | 223 +- tests/utils_tests/test_http.py | 337 +- tests/utils_tests/test_inspect.py | 34 +- tests/utils_tests/test_ipv6.py | 81 +- tests/utils_tests/test_jslex.py | 299 +- tests/utils_tests/test_lazyobject.py | 140 +- tests/utils_tests/test_lorem_ipsum.py | 98 +- .../utils_tests/test_module/another_bad_module.py | 12 +- .../utils_tests/test_module/another_good_module.py | 10 +- tests/utils_tests/test_module/bad_module.py | 2 +- .../test_module/child_module/grandchild_module.py | 2 +- tests/utils_tests/test_module/good_module.py | 2 +- tests/utils_tests/test_module_loading.py | 168 +- tests/utils_tests/test_numberformat.py | 198 +- tests/utils_tests/test_os_utils.py | 9 +- tests/utils_tests/test_regex_helper.py | 25 +- tests/utils_tests/test_safestring.py | 51 +- tests/utils_tests/test_simplelazyobject.py | 3 +- tests/utils_tests/test_termcolors.py | 200 +- tests/utils_tests/test_text.py | 308 +- tests/utils_tests/test_timesince.py | 192 +- tests/utils_tests/test_timezone.py | 156 +- tests/utils_tests/test_topological_sort.py | 16 +- tests/utils_tests/test_tree.py | 32 +- tests/utils_tests/utils.py | 4 +- tests/validation/models.py | 83 +- tests/validation/test_custom_messages.py | 4 +- tests/validation/test_error_messages.py | 88 +- tests/validation/test_picklable.py | 43 +- tests/validation/test_unique.py | 159 +- tests/validation/test_validators.py | 36 +- tests/validation/tests.py | 105 +- tests/validators/tests.py | 1083 ++-- tests/version/tests.py | 37 +- tests/view_tests/default_urls.py | 2 +- tests/view_tests/generic_urls.py | 36 +- tests/view_tests/models.py | 8 +- tests/view_tests/regression_21530_urls.py | 2 +- tests/view_tests/tests/test_csrf.py | 106 +- tests/view_tests/tests/test_debug.py | 1122 ++-- tests/view_tests/tests/test_defaults.py | 170 +- tests/view_tests/tests/test_i18n.py | 438 +- tests/view_tests/tests/test_json.py | 21 +- tests/view_tests/tests/test_specials.py | 7 +- tests/view_tests/tests/test_static.py | 145 +- tests/view_tests/urls.py | 105 +- tests/view_tests/views.py | 132 +- tests/wsgi/tests.py | 41 +- tests/wsgi/urls.py | 4 +- 1305 files changed, 104776 insertions(+), 73239 deletions(-) (limited to 'tests') diff --git a/tests/absolute_url_overrides/tests.py b/tests/absolute_url_overrides/tests.py index 6879283083..b9a7e4cd64 100644 --- a/tests/absolute_url_overrides/tests.py +++ b/tests/absolute_url_overrides/tests.py @@ -3,35 +3,39 @@ from django.test import SimpleTestCase from django.test.utils import isolate_apps -@isolate_apps('absolute_url_overrides') +@isolate_apps("absolute_url_overrides") class AbsoluteUrlOverrideTests(SimpleTestCase): - def test_get_absolute_url(self): """ get_absolute_url() functions as a normal method. """ + def get_absolute_url(o): - return '/test-a/%s/' % o.pk - TestA = self._create_model_class('TestA', get_absolute_url) + return "/test-a/%s/" % o.pk + + TestA = self._create_model_class("TestA", get_absolute_url) - self.assertTrue(hasattr(TestA, 'get_absolute_url')) - obj = TestA(pk=1, name='Foo') - self.assertEqual('/test-a/%s/' % obj.pk, obj.get_absolute_url()) + self.assertTrue(hasattr(TestA, "get_absolute_url")) + obj = TestA(pk=1, name="Foo") + self.assertEqual("/test-a/%s/" % obj.pk, obj.get_absolute_url()) def test_override_get_absolute_url(self): """ ABSOLUTE_URL_OVERRIDES should override get_absolute_url(). """ + def get_absolute_url(o): - return '/test-b/%s/' % o.pk + return "/test-b/%s/" % o.pk + with self.settings( ABSOLUTE_URL_OVERRIDES={ - 'absolute_url_overrides.testb': lambda o: '/overridden-test-b/%s/' % o.pk, + "absolute_url_overrides.testb": lambda o: "/overridden-test-b/%s/" + % o.pk, }, ): - TestB = self._create_model_class('TestB', get_absolute_url) - obj = TestB(pk=1, name='Foo') - self.assertEqual('/overridden-test-b/%s/' % obj.pk, obj.get_absolute_url()) + TestB = self._create_model_class("TestB", get_absolute_url) + obj = TestB(pk=1, name="Foo") + self.assertEqual("/overridden-test-b/%s/" % obj.pk, obj.get_absolute_url()) def test_insert_get_absolute_url(self): """ @@ -40,19 +44,19 @@ class AbsoluteUrlOverrideTests(SimpleTestCase): """ with self.settings( ABSOLUTE_URL_OVERRIDES={ - 'absolute_url_overrides.testc': lambda o: '/test-c/%s/' % o.pk, + "absolute_url_overrides.testc": lambda o: "/test-c/%s/" % o.pk, }, ): - TestC = self._create_model_class('TestC') - obj = TestC(pk=1, name='Foo') - self.assertEqual('/test-c/%s/' % obj.pk, obj.get_absolute_url()) + TestC = self._create_model_class("TestC") + obj = TestC(pk=1, name="Foo") + self.assertEqual("/test-c/%s/" % obj.pk, obj.get_absolute_url()) def _create_model_class(self, class_name, get_absolute_url_method=None): attrs = { - 'name': models.CharField(max_length=50), - '__module__': 'absolute_url_overrides', + "name": models.CharField(max_length=50), + "__module__": "absolute_url_overrides", } if get_absolute_url_method: - attrs['get_absolute_url'] = get_absolute_url_method + attrs["get_absolute_url"] = get_absolute_url_method return type(class_name, (models.Model,), attrs) diff --git a/tests/admin_autodiscover/tests.py b/tests/admin_autodiscover/tests.py index b15060ade8..66de74f2a5 100644 --- a/tests/admin_autodiscover/tests.py +++ b/tests/admin_autodiscover/tests.py @@ -7,11 +7,12 @@ class AdminAutoDiscoverTests(SimpleTestCase): Test for bug #8245 - don't raise an AlreadyRegistered exception when using autodiscover() and an admin.py module contains an error. """ + def test_double_call_autodiscover(self): # The first time autodiscover is called, we should get our real error. - with self.assertRaisesMessage(Exception, 'Bad admin module'): + with self.assertRaisesMessage(Exception, "Bad admin module"): admin.autodiscover() # Calling autodiscover again should raise the very same error it did # the first time, not an AlreadyRegistered error. - with self.assertRaisesMessage(Exception, 'Bad admin module'): + with self.assertRaisesMessage(Exception, "Bad admin module"): admin.autodiscover() diff --git a/tests/admin_changelist/admin.py b/tests/admin_changelist/admin.py index 929539ea88..67187f5b79 100644 --- a/tests/admin_changelist/admin.py +++ b/tests/admin_changelist/admin.py @@ -12,12 +12,14 @@ site.register(User, UserAdmin) class CustomPaginator(Paginator): def __init__(self, queryset, page_size, orphans=0, allow_empty_first_page=True): - super().__init__(queryset, 5, orphans=2, allow_empty_first_page=allow_empty_first_page) + super().__init__( + queryset, 5, orphans=2, allow_empty_first_page=allow_empty_first_page + ) class EventAdmin(admin.ModelAdmin): - date_hierarchy = 'date' - list_display = ['event_date_func'] + date_hierarchy = "date" + list_display = ["event_date_func"] @admin.display def event_date_func(self, event): @@ -31,21 +33,21 @@ site.register(Event, EventAdmin) class ParentAdmin(admin.ModelAdmin): - list_filter = ['child__name'] - search_fields = ['child__name'] - list_select_related = ['child'] + list_filter = ["child__name"] + search_fields = ["child__name"] + list_select_related = ["child"] class ParentAdminTwoSearchFields(admin.ModelAdmin): - list_filter = ['child__name'] - search_fields = ['child__name', 'child__age'] - list_select_related = ['child'] + list_filter = ["child__name"] + search_fields = ["child__name", "child__age"] + list_select_related = ["child"] class ChildAdmin(admin.ModelAdmin): - list_display = ['name', 'parent'] + list_display = ["name", "parent"] list_per_page = 10 - list_filter = ['parent', 'age'] + list_filter = ["parent", "age"] def get_queryset(self, request): return super().get_queryset(request).select_related("parent") @@ -56,32 +58,32 @@ class CustomPaginationAdmin(ChildAdmin): class FilteredChildAdmin(admin.ModelAdmin): - list_display = ['name', 'parent'] + list_display = ["name", "parent"] list_per_page = 10 def get_queryset(self, request): - return super().get_queryset(request).filter(name__contains='filtered') + return super().get_queryset(request).filter(name__contains="filtered") class BandAdmin(admin.ModelAdmin): - list_filter = ['genres'] + list_filter = ["genres"] class NrOfMembersFilter(admin.SimpleListFilter): - title = 'number of members' - parameter_name = 'nr_of_members_partition' + title = "number of members" + parameter_name = "nr_of_members_partition" def lookups(self, request, model_admin): return [ - ('5', '0 - 5'), - ('more', 'more than 5'), + ("5", "0 - 5"), + ("more", "more than 5"), ] def queryset(self, request, queryset): value = self.value() - if value == '5': + if value == "5": return queryset.filter(nr_of_members__lte=5) - if value == 'more': + if value == "more": return queryset.filter(nr_of_members__gt=5) @@ -93,44 +95,44 @@ site.register(Band, BandCallableFilterAdmin) class GroupAdmin(admin.ModelAdmin): - list_filter = ['members'] + list_filter = ["members"] class ConcertAdmin(admin.ModelAdmin): - list_filter = ['group__members'] - search_fields = ['group__members__name'] + list_filter = ["group__members"] + search_fields = ["group__members__name"] class QuartetAdmin(admin.ModelAdmin): - list_filter = ['members'] + list_filter = ["members"] class ChordsBandAdmin(admin.ModelAdmin): - list_filter = ['members'] + list_filter = ["members"] class InvitationAdmin(admin.ModelAdmin): - list_display = ('band', 'player') - list_select_related = ('player',) + list_display = ("band", "player") + list_select_related = ("player",) class DynamicListDisplayChildAdmin(admin.ModelAdmin): - list_display = ('parent', 'name', 'age') + list_display = ("parent", "name", "age") def get_list_display(self, request): my_list_display = super().get_list_display(request) - if request.user.username == 'noparents': + if request.user.username == "noparents": my_list_display = list(my_list_display) - my_list_display.remove('parent') + my_list_display.remove("parent") return my_list_display class DynamicListDisplayLinksChildAdmin(admin.ModelAdmin): - list_display = ('parent', 'name', 'age') - list_display_links = ['parent', 'name'] + list_display = ("parent", "name", "age") + list_display_links = ["parent", "name"] def get_list_display_links(self, request, list_display): - return ['age'] + return ["age"] site.register(Child, DynamicListDisplayChildAdmin) @@ -138,8 +140,8 @@ site.register(Child, DynamicListDisplayChildAdmin) class NoListDisplayLinksParentAdmin(admin.ModelAdmin): list_display_links = None - list_display = ['name'] - list_editable = ['name'] + list_display = ["name"] + list_editable = ["name"] actions_on_bottom = True @@ -148,8 +150,8 @@ site.register(Parent, NoListDisplayLinksParentAdmin) class SwallowAdmin(admin.ModelAdmin): actions = None # prevent ['action_checkbox'] + list(list_display) - list_display = ('origin', 'load', 'speed', 'swallowonetoone') - list_editable = ['load', 'speed'] + list_display = ("origin", "load", "speed", "swallowonetoone") + list_editable = ["load", "speed"] list_per_page = 3 @@ -157,29 +159,29 @@ site.register(Swallow, SwallowAdmin) class DynamicListFilterChildAdmin(admin.ModelAdmin): - list_filter = ('parent', 'name', 'age') + list_filter = ("parent", "name", "age") def get_list_filter(self, request): my_list_filter = super().get_list_filter(request) - if request.user.username == 'noparents': + if request.user.username == "noparents": my_list_filter = list(my_list_filter) - my_list_filter.remove('parent') + my_list_filter.remove("parent") return my_list_filter class DynamicSearchFieldsChildAdmin(admin.ModelAdmin): - search_fields = ('name',) + search_fields = ("name",) def get_search_fields(self, request): search_fields = super().get_search_fields(request) - search_fields += ('age',) + search_fields += ("age",) return search_fields class EmptyValueChildAdmin(admin.ModelAdmin): - empty_value_display = '-empty-' - list_display = ('name', 'age_display', 'age') + empty_value_display = "-empty-" + list_display = ("name", "age_display", "age") - @admin.display(empty_value='†') + @admin.display(empty_value="†") def age_display(self, obj): return obj.age diff --git a/tests/admin_changelist/models.py b/tests/admin_changelist/models.py index 81d7fdfb3a..180c38428a 100644 --- a/tests/admin_changelist/models.py +++ b/tests/admin_changelist/models.py @@ -38,7 +38,7 @@ class Musician(models.Model): class Group(models.Model): name = models.CharField(max_length=30) - members = models.ManyToManyField(Musician, through='Membership') + members = models.ManyToManyField(Musician, through="Membership") def __str__(self): return self.name @@ -65,7 +65,7 @@ class ChordsMusician(Musician): class ChordsBand(models.Model): name = models.CharField(max_length=30) - members = models.ManyToManyField(ChordsMusician, through='Invitation') + members = models.ManyToManyField(ChordsMusician, through="Invitation") class Invitation(models.Model): @@ -81,7 +81,7 @@ class Swallow(models.Model): speed = models.FloatField() class Meta: - ordering = ('speed', 'load') + ordering = ("speed", "load") class SwallowOneToOne(models.Model): @@ -93,12 +93,13 @@ class UnorderedObject(models.Model): Model without any defined `Meta.ordering`. Refs #17198. """ + bool = models.BooleanField(default=True) class OrderedObjectManager(models.Manager): def get_queryset(self): - return super().get_queryset().order_by('number') + return super().get_queryset().order_by("number") class OrderedObject(models.Model): @@ -106,9 +107,10 @@ class OrderedObject(models.Model): Model with Manager that defines a default order. Refs #17198. """ + name = models.CharField(max_length=255) bool = models.BooleanField(default=True) - number = models.IntegerField(default=0, db_column='number_val') + number = models.IntegerField(default=0, db_column="number_val") objects = OrderedObjectManager() diff --git a/tests/admin_changelist/test_date_hierarchy.py b/tests/admin_changelist/test_date_hierarchy.py index a321650b32..a8c10f7cd8 100644 --- a/tests/admin_changelist/test_date_hierarchy.py +++ b/tests/admin_changelist/test_date_hierarchy.py @@ -5,7 +5,8 @@ from django.contrib.auth.models import User from django.test import RequestFactory, TestCase from django.utils.timezone import make_aware -from .admin import EventAdmin, site as custom_site +from .admin import EventAdmin +from .admin import site as custom_site from .models import Event @@ -14,34 +15,48 @@ class DateHierarchyTests(TestCase): @classmethod def setUpTestData(cls): - cls.superuser = User.objects.create_superuser(username='super', email='a@b.com', password='xxx') + cls.superuser = User.objects.create_superuser( + username="super", email="a@b.com", password="xxx" + ) def assertDateParams(self, query, expected_from_date, expected_to_date): - query = {'date__%s' % field: val for field, val in query.items()} - request = self.factory.get('/', query) + query = {"date__%s" % field: val for field, val in query.items()} + request = self.factory.get("/", query) request.user = self.superuser changelist = EventAdmin(Event, custom_site).get_changelist_instance(request) _, _, lookup_params, *_ = changelist.get_filters(request) - self.assertEqual(lookup_params['date__gte'], expected_from_date) - self.assertEqual(lookup_params['date__lt'], expected_to_date) + self.assertEqual(lookup_params["date__gte"], expected_from_date) + self.assertEqual(lookup_params["date__lt"], expected_to_date) def test_bounded_params(self): tests = ( - ({'year': 2017}, datetime(2017, 1, 1), datetime(2018, 1, 1)), - ({'year': 2017, 'month': 2}, datetime(2017, 2, 1), datetime(2017, 3, 1)), - ({'year': 2017, 'month': 12}, datetime(2017, 12, 1), datetime(2018, 1, 1)), - ({'year': 2017, 'month': 12, 'day': 15}, datetime(2017, 12, 15), datetime(2017, 12, 16)), - ({'year': 2017, 'month': 12, 'day': 31}, datetime(2017, 12, 31), datetime(2018, 1, 1)), - ({'year': 2017, 'month': 2, 'day': 28}, datetime(2017, 2, 28), datetime(2017, 3, 1)), + ({"year": 2017}, datetime(2017, 1, 1), datetime(2018, 1, 1)), + ({"year": 2017, "month": 2}, datetime(2017, 2, 1), datetime(2017, 3, 1)), + ({"year": 2017, "month": 12}, datetime(2017, 12, 1), datetime(2018, 1, 1)), + ( + {"year": 2017, "month": 12, "day": 15}, + datetime(2017, 12, 15), + datetime(2017, 12, 16), + ), + ( + {"year": 2017, "month": 12, "day": 31}, + datetime(2017, 12, 31), + datetime(2018, 1, 1), + ), + ( + {"year": 2017, "month": 2, "day": 28}, + datetime(2017, 2, 28), + datetime(2017, 3, 1), + ), ) for query, expected_from_date, expected_to_date in tests: with self.subTest(query=query): self.assertDateParams(query, expected_from_date, expected_to_date) def test_bounded_params_with_time_zone(self): - with self.settings(USE_TZ=True, TIME_ZONE='Asia/Jerusalem'): + with self.settings(USE_TZ=True, TIME_ZONE="Asia/Jerusalem"): self.assertDateParams( - {'year': 2017, 'month': 2, 'day': 28}, + {"year": 2017, "month": 2, "day": 28}, make_aware(datetime(2017, 2, 28)), make_aware(datetime(2017, 3, 1)), ) @@ -49,31 +64,33 @@ class DateHierarchyTests(TestCase): def test_bounded_params_with_dst_time_zone(self): tests = [ # Northern hemisphere. - ('Asia/Jerusalem', 3), - ('Asia/Jerusalem', 10), + ("Asia/Jerusalem", 3), + ("Asia/Jerusalem", 10), # Southern hemisphere. - ('Pacific/Chatham', 4), - ('Pacific/Chatham', 9), + ("Pacific/Chatham", 4), + ("Pacific/Chatham", 9), ] for time_zone, month in tests: with self.subTest(time_zone=time_zone, month=month): with self.settings(USE_TZ=True, TIME_ZONE=time_zone): self.assertDateParams( - {'year': 2019, 'month': month}, + {"year": 2019, "month": month}, make_aware(datetime(2019, month, 1)), make_aware(datetime(2019, month + 1, 1)), ) def test_invalid_params(self): tests = ( - {'year': 'x'}, - {'year': 2017, 'month': 'x'}, - {'year': 2017, 'month': 12, 'day': 'x'}, - {'year': 2017, 'month': 13}, - {'year': 2017, 'month': 12, 'day': 32}, - {'year': 2017, 'month': 0}, - {'year': 2017, 'month': 12, 'day': 0}, + {"year": "x"}, + {"year": 2017, "month": "x"}, + {"year": 2017, "month": 12, "day": "x"}, + {"year": 2017, "month": 13}, + {"year": 2017, "month": 12, "day": 32}, + {"year": 2017, "month": 0}, + {"year": 2017, "month": 12, "day": 0}, ) for invalid_query in tests: - with self.subTest(query=invalid_query), self.assertRaises(IncorrectLookupParameters): + with self.subTest(query=invalid_query), self.assertRaises( + IncorrectLookupParameters + ): self.assertDateParams(invalid_query, None, None) diff --git a/tests/admin_changelist/tests.py b/tests/admin_changelist/tests.py index 86fcab531a..7d6deced7e 100644 --- a/tests/admin_changelist/tests.py +++ b/tests/admin_changelist/tests.py @@ -6,7 +6,12 @@ from django.contrib.admin.options import IncorrectLookupParameters from django.contrib.admin.templatetags.admin_list import pagination from django.contrib.admin.tests import AdminSeleniumTestCase from django.contrib.admin.views.main import ( - ALL_VAR, IS_POPUP_VAR, ORDER_VAR, PAGE_VAR, SEARCH_VAR, TO_FIELD_VAR, + ALL_VAR, + IS_POPUP_VAR, + ORDER_VAR, + PAGE_VAR, + SEARCH_VAR, + TO_FIELD_VAR, ) from django.contrib.auth.models import User from django.contrib.contenttypes.models import ContentType @@ -18,36 +23,64 @@ from django.db.models.lookups import Contains, Exact from django.template import Context, Template, TemplateSyntaxError from django.test import TestCase, override_settings from django.test.client import RequestFactory -from django.test.utils import ( - CaptureQueriesContext, isolate_apps, register_lookup, -) +from django.test.utils import CaptureQueriesContext, isolate_apps, register_lookup from django.urls import reverse from django.utils import formats from .admin import ( - BandAdmin, ChildAdmin, ChordsBandAdmin, ConcertAdmin, - CustomPaginationAdmin, CustomPaginator, DynamicListDisplayChildAdmin, - DynamicListDisplayLinksChildAdmin, DynamicListFilterChildAdmin, - DynamicSearchFieldsChildAdmin, EmptyValueChildAdmin, EventAdmin, - FilteredChildAdmin, GroupAdmin, InvitationAdmin, - NoListDisplayLinksParentAdmin, ParentAdmin, ParentAdminTwoSearchFields, - QuartetAdmin, SwallowAdmin, site as custom_site, + BandAdmin, + ChildAdmin, + ChordsBandAdmin, + ConcertAdmin, + CustomPaginationAdmin, + CustomPaginator, + DynamicListDisplayChildAdmin, + DynamicListDisplayLinksChildAdmin, + DynamicListFilterChildAdmin, + DynamicSearchFieldsChildAdmin, + EmptyValueChildAdmin, + EventAdmin, + FilteredChildAdmin, + GroupAdmin, + InvitationAdmin, + NoListDisplayLinksParentAdmin, + ParentAdmin, + ParentAdminTwoSearchFields, + QuartetAdmin, + SwallowAdmin, ) +from .admin import site as custom_site from .models import ( - Band, CharPK, Child, ChordsBand, ChordsMusician, Concert, CustomIdUser, - Event, Genre, Group, Invitation, Membership, Musician, OrderedObject, - Parent, Quartet, Swallow, SwallowOneToOne, UnorderedObject, + Band, + CharPK, + Child, + ChordsBand, + ChordsMusician, + Concert, + CustomIdUser, + Event, + Genre, + Group, + Invitation, + Membership, + Musician, + OrderedObject, + Parent, + Quartet, + Swallow, + SwallowOneToOne, + UnorderedObject, ) def build_tbody_html(pk, href, extra_fields): return ( - '' + "" '' '' 'name' - '{}' + "{}" ).format(pk, href, extra_fields) @@ -57,10 +90,14 @@ class ChangeListTests(TestCase): @classmethod def setUpTestData(cls): - cls.superuser = User.objects.create_superuser(username='super', email='a@b.com', password='xxx') + cls.superuser = User.objects.create_superuser( + username="super", email="a@b.com", password="xxx" + ) def _create_superuser(self, username): - return User.objects.create_superuser(username=username, email='a@b.com', password='xxx') + return User.objects.create_superuser( + username=username, email="a@b.com", password="xxx" + ) def _mocked_authenticated_request(self, url, user): request = self.factory.get(url) @@ -69,36 +106,36 @@ class ChangeListTests(TestCase): def test_repr(self): m = ChildAdmin(Child, custom_site) - request = self.factory.get('/child/') + request = self.factory.get("/child/") request.user = self.superuser cl = m.get_changelist_instance(request) - self.assertEqual(repr(cl), '') + self.assertEqual(repr(cl), "") def test_specified_ordering_by_f_expression(self): class OrderedByFBandAdmin(admin.ModelAdmin): - list_display = ['name', 'genres', 'nr_of_members'] + list_display = ["name", "genres", "nr_of_members"] ordering = ( - F('nr_of_members').desc(nulls_last=True), - Upper(F('name')).asc(), - F('genres').asc(), + F("nr_of_members").desc(nulls_last=True), + Upper(F("name")).asc(), + F("genres").asc(), ) m = OrderedByFBandAdmin(Band, custom_site) - request = self.factory.get('/band/') + request = self.factory.get("/band/") request.user = self.superuser cl = m.get_changelist_instance(request) - self.assertEqual(cl.get_ordering_field_columns(), {3: 'desc', 2: 'asc'}) + self.assertEqual(cl.get_ordering_field_columns(), {3: "desc", 2: "asc"}) def test_specified_ordering_by_f_expression_without_asc_desc(self): class OrderedByFBandAdmin(admin.ModelAdmin): - list_display = ['name', 'genres', 'nr_of_members'] - ordering = (F('nr_of_members'), Upper('name'), F('genres')) + list_display = ["name", "genres", "nr_of_members"] + ordering = (F("nr_of_members"), Upper("name"), F("genres")) m = OrderedByFBandAdmin(Band, custom_site) - request = self.factory.get('/band/') + request = self.factory.get("/band/") request.user = self.superuser cl = m.get_changelist_instance(request) - self.assertEqual(cl.get_ordering_field_columns(), {3: 'asc', 2: 'asc'}) + self.assertEqual(cl.get_ordering_field_columns(), {3: "asc", 2: "asc"}) def test_select_related_preserved(self): """ @@ -106,85 +143,85 @@ class ChangeListTests(TestCase): overwrite a custom select_related provided by ModelAdmin.get_queryset(). """ m = ChildAdmin(Child, custom_site) - request = self.factory.get('/child/') + request = self.factory.get("/child/") request.user = self.superuser cl = m.get_changelist_instance(request) - self.assertEqual(cl.queryset.query.select_related, {'parent': {}}) + self.assertEqual(cl.queryset.query.select_related, {"parent": {}}) def test_select_related_preserved_when_multi_valued_in_search_fields(self): - parent = Parent.objects.create(name='Mary') - Child.objects.create(parent=parent, name='Danielle') - Child.objects.create(parent=parent, name='Daniel') + parent = Parent.objects.create(name="Mary") + Child.objects.create(parent=parent, name="Danielle") + Child.objects.create(parent=parent, name="Daniel") m = ParentAdmin(Parent, custom_site) - request = self.factory.get('/parent/', data={SEARCH_VAR: 'daniel'}) + request = self.factory.get("/parent/", data={SEARCH_VAR: "daniel"}) request.user = self.superuser cl = m.get_changelist_instance(request) self.assertEqual(cl.queryset.count(), 1) # select_related is preserved. - self.assertEqual(cl.queryset.query.select_related, {'child': {}}) + self.assertEqual(cl.queryset.query.select_related, {"child": {}}) def test_select_related_as_tuple(self): ia = InvitationAdmin(Invitation, custom_site) - request = self.factory.get('/invitation/') + request = self.factory.get("/invitation/") request.user = self.superuser cl = ia.get_changelist_instance(request) - self.assertEqual(cl.queryset.query.select_related, {'player': {}}) + self.assertEqual(cl.queryset.query.select_related, {"player": {}}) def test_select_related_as_empty_tuple(self): ia = InvitationAdmin(Invitation, custom_site) ia.list_select_related = () - request = self.factory.get('/invitation/') + request = self.factory.get("/invitation/") request.user = self.superuser cl = ia.get_changelist_instance(request) self.assertIs(cl.queryset.query.select_related, False) def test_get_select_related_custom_method(self): class GetListSelectRelatedAdmin(admin.ModelAdmin): - list_display = ('band', 'player') + list_display = ("band", "player") def get_list_select_related(self, request): - return ('band', 'player') + return ("band", "player") ia = GetListSelectRelatedAdmin(Invitation, custom_site) - request = self.factory.get('/invitation/') + request = self.factory.get("/invitation/") request.user = self.superuser cl = ia.get_changelist_instance(request) - self.assertEqual(cl.queryset.query.select_related, {'player': {}, 'band': {}}) + self.assertEqual(cl.queryset.query.select_related, {"player": {}, "band": {}}) def test_many_search_terms(self): - parent = Parent.objects.create(name='Mary') - Child.objects.create(parent=parent, name='Danielle') - Child.objects.create(parent=parent, name='Daniel') + parent = Parent.objects.create(name="Mary") + Child.objects.create(parent=parent, name="Danielle") + Child.objects.create(parent=parent, name="Daniel") m = ParentAdmin(Parent, custom_site) - request = self.factory.get('/parent/', data={SEARCH_VAR: 'daniel ' * 80}) + request = self.factory.get("/parent/", data={SEARCH_VAR: "daniel " * 80}) request.user = self.superuser cl = m.get_changelist_instance(request) with CaptureQueriesContext(connection) as context: object_count = cl.queryset.count() self.assertEqual(object_count, 1) - self.assertEqual(context.captured_queries[0]['sql'].count('JOIN'), 1) + self.assertEqual(context.captured_queries[0]["sql"].count("JOIN"), 1) def test_related_field_multiple_search_terms(self): """ Searches over multi-valued relationships return rows from related models only when all searched fields match that row. """ - parent = Parent.objects.create(name='Mary') - Child.objects.create(parent=parent, name='Danielle', age=18) - Child.objects.create(parent=parent, name='Daniel', age=19) + parent = Parent.objects.create(name="Mary") + Child.objects.create(parent=parent, name="Danielle", age=18) + Child.objects.create(parent=parent, name="Daniel", age=19) m = ParentAdminTwoSearchFields(Parent, custom_site) - request = self.factory.get('/parent/', data={SEARCH_VAR: 'danielle 19'}) + request = self.factory.get("/parent/", data={SEARCH_VAR: "danielle 19"}) request.user = self.superuser cl = m.get_changelist_instance(request) self.assertEqual(cl.queryset.count(), 0) - request = self.factory.get('/parent/', data={SEARCH_VAR: 'daniel 19'}) + request = self.factory.get("/parent/", data={SEARCH_VAR: "daniel 19"}) request.user = self.superuser cl = m.get_changelist_instance(request) self.assertEqual(cl.queryset.count(), 1) @@ -194,78 +231,108 @@ class ChangeListTests(TestCase): Regression test for #14982: EMPTY_CHANGELIST_VALUE should be honored for relationship fields """ - new_child = Child.objects.create(name='name', parent=None) - request = self.factory.get('/child/') + new_child = Child.objects.create(name="name", parent=None) + request = self.factory.get("/child/") request.user = self.superuser m = ChildAdmin(Child, custom_site) cl = m.get_changelist_instance(request) cl.formset = None - template = Template('{% load admin_list %}{% spaceless %}{% result_list cl %}{% endspaceless %}') - context = Context({'cl': cl, 'opts': Child._meta}) + template = Template( + "{% load admin_list %}{% spaceless %}{% result_list cl %}{% endspaceless %}" + ) + context = Context({"cl": cl, "opts": Child._meta}) table_output = template.render(context) - link = reverse('admin:admin_changelist_child_change', args=(new_child.id,)) - row_html = build_tbody_html(new_child.id, link, '-') - self.assertNotEqual(table_output.find(row_html), -1, 'Failed to find expected row element: %s' % table_output) + link = reverse("admin:admin_changelist_child_change", args=(new_child.id,)) + row_html = build_tbody_html( + new_child.id, link, '-' + ) + self.assertNotEqual( + table_output.find(row_html), + -1, + "Failed to find expected row element: %s" % table_output, + ) def test_result_list_set_empty_value_display_on_admin_site(self): """ Empty value display can be set on AdminSite. """ - new_child = Child.objects.create(name='name', parent=None) - request = self.factory.get('/child/') + new_child = Child.objects.create(name="name", parent=None) + request = self.factory.get("/child/") request.user = self.superuser # Set a new empty display value on AdminSite. - admin.site.empty_value_display = '???' + admin.site.empty_value_display = "???" m = ChildAdmin(Child, admin.site) cl = m.get_changelist_instance(request) cl.formset = None - template = Template('{% load admin_list %}{% spaceless %}{% result_list cl %}{% endspaceless %}') - context = Context({'cl': cl, 'opts': Child._meta}) + template = Template( + "{% load admin_list %}{% spaceless %}{% result_list cl %}{% endspaceless %}" + ) + context = Context({"cl": cl, "opts": Child._meta}) table_output = template.render(context) - link = reverse('admin:admin_changelist_child_change', args=(new_child.id,)) - row_html = build_tbody_html(new_child.id, link, '???') - self.assertNotEqual(table_output.find(row_html), -1, 'Failed to find expected row element: %s' % table_output) + link = reverse("admin:admin_changelist_child_change", args=(new_child.id,)) + row_html = build_tbody_html( + new_child.id, link, '???' + ) + self.assertNotEqual( + table_output.find(row_html), + -1, + "Failed to find expected row element: %s" % table_output, + ) def test_result_list_set_empty_value_display_in_model_admin(self): """ Empty value display can be set in ModelAdmin or individual fields. """ - new_child = Child.objects.create(name='name', parent=None) - request = self.factory.get('/child/') + new_child = Child.objects.create(name="name", parent=None) + request = self.factory.get("/child/") request.user = self.superuser m = EmptyValueChildAdmin(Child, admin.site) cl = m.get_changelist_instance(request) cl.formset = None - template = Template('{% load admin_list %}{% spaceless %}{% result_list cl %}{% endspaceless %}') - context = Context({'cl': cl, 'opts': Child._meta}) + template = Template( + "{% load admin_list %}{% spaceless %}{% result_list cl %}{% endspaceless %}" + ) + context = Context({"cl": cl, "opts": Child._meta}) table_output = template.render(context) - link = reverse('admin:admin_changelist_child_change', args=(new_child.id,)) + link = reverse("admin:admin_changelist_child_change", args=(new_child.id,)) row_html = build_tbody_html( new_child.id, link, '†' - '-empty-' + '-empty-', + ) + self.assertNotEqual( + table_output.find(row_html), + -1, + "Failed to find expected row element: %s" % table_output, ) - self.assertNotEqual(table_output.find(row_html), -1, 'Failed to find expected row element: %s' % table_output) def test_result_list_html(self): """ Inclusion tag result_list generates a table when with default ModelAdmin settings. """ - new_parent = Parent.objects.create(name='parent') - new_child = Child.objects.create(name='name', parent=new_parent) - request = self.factory.get('/child/') + new_parent = Parent.objects.create(name="parent") + new_child = Child.objects.create(name="name", parent=new_parent) + request = self.factory.get("/child/") request.user = self.superuser m = ChildAdmin(Child, custom_site) cl = m.get_changelist_instance(request) cl.formset = None - template = Template('{% load admin_list %}{% spaceless %}{% result_list cl %}{% endspaceless %}') - context = Context({'cl': cl, 'opts': Child._meta}) + template = Template( + "{% load admin_list %}{% spaceless %}{% result_list cl %}{% endspaceless %}" + ) + context = Context({"cl": cl, "opts": Child._meta}) table_output = template.render(context) - link = reverse('admin:admin_changelist_child_change', args=(new_child.id,)) - row_html = build_tbody_html(new_child.id, link, '%s' % new_parent) - self.assertNotEqual(table_output.find(row_html), -1, 'Failed to find expected row element: %s' % table_output) + link = reverse("admin:admin_changelist_child_change", args=(new_child.id,)) + row_html = build_tbody_html( + new_child.id, link, '%s' % new_parent + ) + self.assertNotEqual( + table_output.find(row_html), + -1, + "Failed to find expected row element: %s" % table_output, + ) def test_result_list_editable_html(self): """ @@ -276,29 +343,33 @@ class ChangeListTests(TestCase): when list_editable is enabled are rendered in a div outside the table. """ - new_parent = Parent.objects.create(name='parent') - new_child = Child.objects.create(name='name', parent=new_parent) - request = self.factory.get('/child/') + new_parent = Parent.objects.create(name="parent") + new_child = Child.objects.create(name="name", parent=new_parent) + request = self.factory.get("/child/") request.user = self.superuser m = ChildAdmin(Child, custom_site) # Test with list_editable fields - m.list_display = ['id', 'name', 'parent'] - m.list_display_links = ['id'] - m.list_editable = ['name'] + m.list_display = ["id", "name", "parent"] + m.list_display_links = ["id"] + m.list_editable = ["name"] cl = m.get_changelist_instance(request) FormSet = m.get_changelist_formset(request) cl.formset = FormSet(queryset=cl.result_list) - template = Template('{% load admin_list %}{% spaceless %}{% result_list cl %}{% endspaceless %}') - context = Context({'cl': cl, 'opts': Child._meta}) + template = Template( + "{% load admin_list %}{% spaceless %}{% result_list cl %}{% endspaceless %}" + ) + context = Context({"cl": cl, "opts": Child._meta}) table_output = template.render(context) # make sure that hidden fields are in the correct place hiddenfields_div = ( '
' '' - '
' + "" ) % new_child.id - self.assertInHTML(hiddenfields_div, table_output, msg_prefix='Failed to find hidden fields') + self.assertInHTML( + hiddenfields_div, table_output, msg_prefix="Failed to find hidden fields" + ) # make sure that list editable fields are rendered in divs correctly editable_name_field = ( @@ -315,26 +386,26 @@ class ChangeListTests(TestCase): """ Regression test for #14312: list_editable with pagination """ - new_parent = Parent.objects.create(name='parent') + new_parent = Parent.objects.create(name="parent") for i in range(1, 201): - Child.objects.create(name='name %s' % i, parent=new_parent) - request = self.factory.get('/child/', data={'p': -1}) # Anything outside range + Child.objects.create(name="name %s" % i, parent=new_parent) + request = self.factory.get("/child/", data={"p": -1}) # Anything outside range request.user = self.superuser m = ChildAdmin(Child, custom_site) # Test with list_editable fields - m.list_display = ['id', 'name', 'parent'] - m.list_display_links = ['id'] - m.list_editable = ['name'] + m.list_display = ["id", "name", "parent"] + m.list_display_links = ["id"] + m.list_editable = ["name"] with self.assertRaises(IncorrectLookupParameters): m.get_changelist_instance(request) def test_custom_paginator(self): - new_parent = Parent.objects.create(name='parent') + new_parent = Parent.objects.create(name="parent") for i in range(1, 201): - Child.objects.create(name='name %s' % i, parent=new_parent) + Child.objects.create(name="name %s" % i, parent=new_parent) - request = self.factory.get('/child/') + request = self.factory.get("/child/") request.user = self.superuser m = CustomPaginationAdmin(Child, custom_site) @@ -347,14 +418,14 @@ class ChangeListTests(TestCase): Regression test for #13902: When using a ManyToMany in list_filter, results shouldn't appear more than once. Basic ManyToMany. """ - blues = Genre.objects.create(name='Blues') - band = Band.objects.create(name='B.B. King Review', nr_of_members=11) + blues = Genre.objects.create(name="Blues") + band = Band.objects.create(name="B.B. King Review", nr_of_members=11) band.genres.add(blues) band.genres.add(blues) m = BandAdmin(Band, custom_site) - request = self.factory.get('/band/', data={'genres': blues.pk}) + request = self.factory.get("/band/", data={"genres": blues.pk}) request.user = self.superuser cl = m.get_changelist_instance(request) @@ -372,13 +443,13 @@ class ChangeListTests(TestCase): Regression test for #13902: When using a ManyToMany in list_filter, results shouldn't appear more than once. With an intermediate model. """ - lead = Musician.objects.create(name='Vox') - band = Group.objects.create(name='The Hype') - Membership.objects.create(group=band, music=lead, role='lead voice') - Membership.objects.create(group=band, music=lead, role='bass player') + lead = Musician.objects.create(name="Vox") + band = Group.objects.create(name="The Hype") + Membership.objects.create(group=band, music=lead, role="lead voice") + Membership.objects.create(group=band, music=lead, role="bass player") m = GroupAdmin(Group, custom_site) - request = self.factory.get('/group/', data={'members': lead.pk}) + request = self.factory.get("/group/", data={"members": lead.pk}) request.user = self.superuser cl = m.get_changelist_instance(request) @@ -396,14 +467,14 @@ class ChangeListTests(TestCase): When using a ManyToMany in list_filter at the second level behind a ForeignKey, results shouldn't appear more than once. """ - lead = Musician.objects.create(name='Vox') - band = Group.objects.create(name='The Hype') - Concert.objects.create(name='Woodstock', group=band) - Membership.objects.create(group=band, music=lead, role='lead voice') - Membership.objects.create(group=band, music=lead, role='bass player') + lead = Musician.objects.create(name="Vox") + band = Group.objects.create(name="The Hype") + Concert.objects.create(name="Woodstock", group=band) + Membership.objects.create(group=band, music=lead, role="lead voice") + Membership.objects.create(group=band, music=lead, role="bass player") m = ConcertAdmin(Concert, custom_site) - request = self.factory.get('/concert/', data={'group__members': lead.pk}) + request = self.factory.get("/concert/", data={"group__members": lead.pk}) request.user = self.superuser cl = m.get_changelist_instance(request) @@ -422,13 +493,13 @@ class ChangeListTests(TestCase): results shouldn't appear more than once. Model managed in the admin inherits from the one that defines the relationship. """ - lead = Musician.objects.create(name='John') - four = Quartet.objects.create(name='The Beatles') - Membership.objects.create(group=four, music=lead, role='lead voice') - Membership.objects.create(group=four, music=lead, role='guitar player') + lead = Musician.objects.create(name="John") + four = Quartet.objects.create(name="The Beatles") + Membership.objects.create(group=four, music=lead, role="lead voice") + Membership.objects.create(group=four, music=lead, role="guitar player") m = QuartetAdmin(Quartet, custom_site) - request = self.factory.get('/quartet/', data={'members': lead.pk}) + request = self.factory.get("/quartet/", data={"members": lead.pk}) request.user = self.superuser cl = m.get_changelist_instance(request) @@ -447,13 +518,13 @@ class ChangeListTests(TestCase): results shouldn't appear more than once. Target of the relationship inherits from another. """ - lead = ChordsMusician.objects.create(name='Player A') - three = ChordsBand.objects.create(name='The Chords Trio') - Invitation.objects.create(band=three, player=lead, instrument='guitar') - Invitation.objects.create(band=three, player=lead, instrument='bass') + lead = ChordsMusician.objects.create(name="Player A") + three = ChordsBand.objects.create(name="The Chords Trio") + Invitation.objects.create(band=three, player=lead, instrument="guitar") + Invitation.objects.create(band=three, player=lead, instrument="bass") m = ChordsBandAdmin(ChordsBand, custom_site) - request = self.factory.get('/chordsband/', data={'members': lead.pk}) + request = self.factory.get("/chordsband/", data={"members": lead.pk}) request.user = self.superuser cl = m.get_changelist_instance(request) @@ -471,13 +542,13 @@ class ChangeListTests(TestCase): Regressions tests for #15819: If a field listed in list_filters is a non-unique related object, results shouldn't appear more than once. """ - parent = Parent.objects.create(name='Mary') + parent = Parent.objects.create(name="Mary") # Two children with the same name - Child.objects.create(parent=parent, name='Daniel') - Child.objects.create(parent=parent, name='Daniel') + Child.objects.create(parent=parent, name="Daniel") + Child.objects.create(parent=parent, name="Daniel") m = ParentAdmin(Parent, custom_site) - request = self.factory.get('/parent/', data={'child__name': 'Daniel'}) + request = self.factory.get("/parent/", data={"child__name": "Daniel"}) request.user = self.superuser cl = m.get_changelist_instance(request) @@ -491,12 +562,12 @@ class ChangeListTests(TestCase): def test_changelist_search_form_validation(self): m = ConcertAdmin(Concert, custom_site) tests = [ - ({SEARCH_VAR: '\x00'}, 'Null characters are not allowed.'), - ({SEARCH_VAR: 'some\x00thing'}, 'Null characters are not allowed.'), + ({SEARCH_VAR: "\x00"}, "Null characters are not allowed."), + ({SEARCH_VAR: "some\x00thing"}, "Null characters are not allowed."), ] for case, error in tests: with self.subTest(case=case): - request = self.factory.get('/concert/', case) + request = self.factory.get("/concert/", case) request.user = self.superuser request._messages = CookieStorage(request) m.get_changelist_instance(request) @@ -509,12 +580,12 @@ class ChangeListTests(TestCase): Regressions tests for #15819: If a field listed in search_fields is a non-unique related object, Exists() must be applied. """ - parent = Parent.objects.create(name='Mary') - Child.objects.create(parent=parent, name='Danielle') - Child.objects.create(parent=parent, name='Daniel') + parent = Parent.objects.create(name="Mary") + Child.objects.create(parent=parent, name="Danielle") + Child.objects.create(parent=parent, name="Daniel") m = ParentAdmin(Parent, custom_site) - request = self.factory.get('/parent/', data={SEARCH_VAR: 'daniel'}) + request = self.factory.get("/parent/", data={SEARCH_VAR: "daniel"}) request.user = self.superuser cl = m.get_changelist_instance(request) @@ -531,14 +602,14 @@ class ChangeListTests(TestCase): ForeignKey, Exists() must be applied and results shouldn't appear more than once. """ - lead = Musician.objects.create(name='Vox') - band = Group.objects.create(name='The Hype') - Concert.objects.create(name='Woodstock', group=band) - Membership.objects.create(group=band, music=lead, role='lead voice') - Membership.objects.create(group=band, music=lead, role='bass player') + lead = Musician.objects.create(name="Vox") + band = Group.objects.create(name="The Hype") + Concert.objects.create(name="Woodstock", group=band) + Membership.objects.create(group=band, music=lead, role="lead voice") + Membership.objects.create(group=band, music=lead, role="bass player") m = ConcertAdmin(Concert, custom_site) - request = self.factory.get('/concert/', data={SEARCH_VAR: 'vox'}) + request = self.factory.get("/concert/", data={SEARCH_VAR: "vox"}) request.user = self.superuser cl = m.get_changelist_instance(request) @@ -554,139 +625,143 @@ class ChangeListTests(TestCase): All rows containing each of the searched words are returned, where each word must be in one of search_fields. """ - band_duo = Group.objects.create(name='Duo') - band_hype = Group.objects.create(name='The Hype') - mary = Musician.objects.create(name='Mary Halvorson') - jonathan = Musician.objects.create(name='Jonathan Finlayson') + band_duo = Group.objects.create(name="Duo") + band_hype = Group.objects.create(name="The Hype") + mary = Musician.objects.create(name="Mary Halvorson") + jonathan = Musician.objects.create(name="Jonathan Finlayson") band_duo.members.set([mary, jonathan]) - Concert.objects.create(name='Tiny desk concert', group=band_duo) - Concert.objects.create(name='Woodstock concert', group=band_hype) + Concert.objects.create(name="Tiny desk concert", group=band_duo) + Concert.objects.create(name="Woodstock concert", group=band_hype) # FK lookup. concert_model_admin = ConcertAdmin(Concert, custom_site) - concert_model_admin.search_fields = ['group__name', 'name'] + concert_model_admin.search_fields = ["group__name", "name"] # Reverse FK lookup. group_model_admin = GroupAdmin(Group, custom_site) - group_model_admin.search_fields = ['name', 'concert__name', 'members__name'] + group_model_admin.search_fields = ["name", "concert__name", "members__name"] for search_string, result_count in ( - ('Duo Concert', 1), - ('Tiny Desk Concert', 1), - ('Concert', 2), - ('Other Concert', 0), - ('Duo Woodstock', 0), + ("Duo Concert", 1), + ("Tiny Desk Concert", 1), + ("Concert", 2), + ("Other Concert", 0), + ("Duo Woodstock", 0), ): with self.subTest(search_string=search_string): # FK lookup. - request = self.factory.get('/concert/', data={SEARCH_VAR: search_string}) + request = self.factory.get( + "/concert/", data={SEARCH_VAR: search_string} + ) request.user = self.superuser - concert_changelist = concert_model_admin.get_changelist_instance(request) + concert_changelist = concert_model_admin.get_changelist_instance( + request + ) self.assertEqual(concert_changelist.queryset.count(), result_count) # Reverse FK lookup. - request = self.factory.get('/group/', data={SEARCH_VAR: search_string}) + request = self.factory.get("/group/", data={SEARCH_VAR: search_string}) request.user = self.superuser group_changelist = group_model_admin.get_changelist_instance(request) self.assertEqual(group_changelist.queryset.count(), result_count) # Many-to-many lookup. for search_string, result_count in ( - ('Finlayson Duo Tiny', 1), - ('Finlayson', 1), - ('Finlayson Hype', 0), - ('Jonathan Finlayson Duo', 1), - ('Mary Jonathan Duo', 0), - ('Oscar Finlayson Duo', 0), + ("Finlayson Duo Tiny", 1), + ("Finlayson", 1), + ("Finlayson Hype", 0), + ("Jonathan Finlayson Duo", 1), + ("Mary Jonathan Duo", 0), + ("Oscar Finlayson Duo", 0), ): with self.subTest(search_string=search_string): - request = self.factory.get('/group/', data={SEARCH_VAR: search_string}) + request = self.factory.get("/group/", data={SEARCH_VAR: search_string}) request.user = self.superuser group_changelist = group_model_admin.get_changelist_instance(request) self.assertEqual(group_changelist.queryset.count(), result_count) def test_pk_in_search_fields(self): - band = Group.objects.create(name='The Hype') - Concert.objects.create(name='Woodstock', group=band) + band = Group.objects.create(name="The Hype") + Concert.objects.create(name="Woodstock", group=band) m = ConcertAdmin(Concert, custom_site) - m.search_fields = ['group__pk'] + m.search_fields = ["group__pk"] - request = self.factory.get('/concert/', data={SEARCH_VAR: band.pk}) + request = self.factory.get("/concert/", data={SEARCH_VAR: band.pk}) request.user = self.superuser cl = m.get_changelist_instance(request) self.assertEqual(cl.queryset.count(), 1) - request = self.factory.get('/concert/', data={SEARCH_VAR: band.pk + 5}) + request = self.factory.get("/concert/", data={SEARCH_VAR: band.pk + 5}) request.user = self.superuser cl = m.get_changelist_instance(request) self.assertEqual(cl.queryset.count(), 0) def test_builtin_lookup_in_search_fields(self): - band = Group.objects.create(name='The Hype') - concert = Concert.objects.create(name='Woodstock', group=band) + band = Group.objects.create(name="The Hype") + concert = Concert.objects.create(name="Woodstock", group=band) m = ConcertAdmin(Concert, custom_site) - m.search_fields = ['name__iexact'] + m.search_fields = ["name__iexact"] - request = self.factory.get('/', data={SEARCH_VAR: 'woodstock'}) + request = self.factory.get("/", data={SEARCH_VAR: "woodstock"}) request.user = self.superuser cl = m.get_changelist_instance(request) self.assertCountEqual(cl.queryset, [concert]) - request = self.factory.get('/', data={SEARCH_VAR: 'wood'}) + request = self.factory.get("/", data={SEARCH_VAR: "wood"}) request.user = self.superuser cl = m.get_changelist_instance(request) self.assertCountEqual(cl.queryset, []) def test_custom_lookup_in_search_fields(self): - band = Group.objects.create(name='The Hype') - concert = Concert.objects.create(name='Woodstock', group=band) + band = Group.objects.create(name="The Hype") + concert = Concert.objects.create(name="Woodstock", group=band) m = ConcertAdmin(Concert, custom_site) - m.search_fields = ['group__name__cc'] - with register_lookup(Field, Contains, lookup_name='cc'): - request = self.factory.get('/', data={SEARCH_VAR: 'Hype'}) + m.search_fields = ["group__name__cc"] + with register_lookup(Field, Contains, lookup_name="cc"): + request = self.factory.get("/", data={SEARCH_VAR: "Hype"}) request.user = self.superuser cl = m.get_changelist_instance(request) self.assertCountEqual(cl.queryset, [concert]) - request = self.factory.get('/', data={SEARCH_VAR: 'Woodstock'}) + request = self.factory.get("/", data={SEARCH_VAR: "Woodstock"}) request.user = self.superuser cl = m.get_changelist_instance(request) self.assertCountEqual(cl.queryset, []) def test_spanning_relations_with_custom_lookup_in_search_fields(self): - hype = Group.objects.create(name='The Hype') - concert = Concert.objects.create(name='Woodstock', group=hype) - vox = Musician.objects.create(name='Vox', age=20) + hype = Group.objects.create(name="The Hype") + concert = Concert.objects.create(name="Woodstock", group=hype) + vox = Musician.objects.create(name="Vox", age=20) Membership.objects.create(music=vox, group=hype) # Register a custom lookup on IntegerField to ensure that field # traversing logic in ModelAdmin.get_search_results() works. - with register_lookup(IntegerField, Exact, lookup_name='exactly'): + with register_lookup(IntegerField, Exact, lookup_name="exactly"): m = ConcertAdmin(Concert, custom_site) - m.search_fields = ['group__members__age__exactly'] + m.search_fields = ["group__members__age__exactly"] - request = self.factory.get('/', data={SEARCH_VAR: '20'}) + request = self.factory.get("/", data={SEARCH_VAR: "20"}) request.user = self.superuser cl = m.get_changelist_instance(request) self.assertCountEqual(cl.queryset, [concert]) - request = self.factory.get('/', data={SEARCH_VAR: '21'}) + request = self.factory.get("/", data={SEARCH_VAR: "21"}) request.user = self.superuser cl = m.get_changelist_instance(request) self.assertCountEqual(cl.queryset, []) def test_custom_lookup_with_pk_shortcut(self): - self.assertEqual(CharPK._meta.pk.name, 'char_pk') # Not equal to 'pk'. + self.assertEqual(CharPK._meta.pk.name, "char_pk") # Not equal to 'pk'. m = admin.ModelAdmin(CustomIdUser, custom_site) - abc = CharPK.objects.create(char_pk='abc') - abcd = CharPK.objects.create(char_pk='abcd') + abc = CharPK.objects.create(char_pk="abc") + abcd = CharPK.objects.create(char_pk="abcd") m = admin.ModelAdmin(CharPK, custom_site) - m.search_fields = ['pk__exact'] + m.search_fields = ["pk__exact"] - request = self.factory.get('/', data={SEARCH_VAR: 'abc'}) + request = self.factory.get("/", data={SEARCH_VAR: "abc"}) request.user = self.superuser cl = m.get_changelist_instance(request) self.assertCountEqual(cl.queryset, [abc]) - request = self.factory.get('/', data={SEARCH_VAR: 'abcd'}) + request = self.factory.get("/", data={SEARCH_VAR: "abcd"}) request.user = self.superuser cl = m.get_changelist_instance(request) self.assertCountEqual(cl.queryset, [abcd]) @@ -697,29 +772,29 @@ class ChangeListTests(TestCase): the changelist's query shouldn't have Exists(). """ m = BandAdmin(Band, custom_site) - for lookup_params in ({}, {'name': 'test'}): - request = self.factory.get('/band/', lookup_params) + for lookup_params in ({}, {"name": "test"}): + request = self.factory.get("/band/", lookup_params) request.user = self.superuser cl = m.get_changelist_instance(request) - self.assertNotIn(' EXISTS', str(cl.queryset.query)) + self.assertNotIn(" EXISTS", str(cl.queryset.query)) # A ManyToManyField in params does have Exists() applied. - request = self.factory.get('/band/', {'genres': '0'}) + request = self.factory.get("/band/", {"genres": "0"}) request.user = self.superuser cl = m.get_changelist_instance(request) - self.assertIn(' EXISTS', str(cl.queryset.query)) + self.assertIn(" EXISTS", str(cl.queryset.query)) def test_pagination(self): """ Regression tests for #12893: Pagination in admins changelist doesn't use queryset set by modeladmin. """ - parent = Parent.objects.create(name='anything') + parent = Parent.objects.create(name="anything") for i in range(1, 31): - Child.objects.create(name='name %s' % i, parent=parent) - Child.objects.create(name='filtered %s' % i, parent=parent) + Child.objects.create(name="name %s" % i, parent=parent) + Child.objects.create(name="filtered %s" % i, parent=parent) - request = self.factory.get('/child/') + request = self.factory.get("/child/") request.user = self.superuser # Test default queryset @@ -743,7 +818,7 @@ class ChangeListTests(TestCase): """ self.client.force_login(self.superuser) event = Event.objects.create(date=datetime.date.today()) - response = self.client.get(reverse('admin:admin_changelist_event_changelist')) + response = self.client.get(reverse("admin:admin_changelist_event_changelist")) self.assertContains(response, formats.localize(event.date)) self.assertNotContains(response, str(event.date)) @@ -751,52 +826,52 @@ class ChangeListTests(TestCase): """ Regression tests for #14206: dynamic list_display support. """ - parent = Parent.objects.create(name='parent') + parent = Parent.objects.create(name="parent") for i in range(10): - Child.objects.create(name='child %s' % i, parent=parent) + Child.objects.create(name="child %s" % i, parent=parent) - user_noparents = self._create_superuser('noparents') - user_parents = self._create_superuser('parents') + user_noparents = self._create_superuser("noparents") + user_parents = self._create_superuser("parents") # Test with user 'noparents' m = custom_site._registry[Child] - request = self._mocked_authenticated_request('/child/', user_noparents) + request = self._mocked_authenticated_request("/child/", user_noparents) response = m.changelist_view(request) - self.assertNotContains(response, 'Parent object') + self.assertNotContains(response, "Parent object") list_display = m.get_list_display(request) list_display_links = m.get_list_display_links(request, list_display) - self.assertEqual(list_display, ['name', 'age']) - self.assertEqual(list_display_links, ['name']) + self.assertEqual(list_display, ["name", "age"]) + self.assertEqual(list_display_links, ["name"]) # Test with user 'parents' m = DynamicListDisplayChildAdmin(Child, custom_site) - request = self._mocked_authenticated_request('/child/', user_parents) + request = self._mocked_authenticated_request("/child/", user_parents) response = m.changelist_view(request) - self.assertContains(response, 'Parent object') + self.assertContains(response, "Parent object") custom_site.unregister(Child) list_display = m.get_list_display(request) list_display_links = m.get_list_display_links(request, list_display) - self.assertEqual(list_display, ('parent', 'name', 'age')) - self.assertEqual(list_display_links, ['parent']) + self.assertEqual(list_display, ("parent", "name", "age")) + self.assertEqual(list_display_links, ["parent"]) # Test default implementation custom_site.register(Child, ChildAdmin) m = custom_site._registry[Child] - request = self._mocked_authenticated_request('/child/', user_noparents) + request = self._mocked_authenticated_request("/child/", user_noparents) response = m.changelist_view(request) - self.assertContains(response, 'Parent object') + self.assertContains(response, "Parent object") def test_show_all(self): - parent = Parent.objects.create(name='anything') + parent = Parent.objects.create(name="anything") for i in range(1, 31): - Child.objects.create(name='name %s' % i, parent=parent) - Child.objects.create(name='filtered %s' % i, parent=parent) + Child.objects.create(name="name %s" % i, parent=parent) + Child.objects.create(name="filtered %s" % i, parent=parent) # Add "show all" parameter to request - request = self.factory.get('/child/', data={ALL_VAR: ''}) + request = self.factory.get("/child/", data={ALL_VAR: ""}) request.user = self.superuser # Test valid "show all" request (number of total objects is under max) @@ -820,52 +895,52 @@ class ChangeListTests(TestCase): """ Regression tests for #16257: dynamic list_display_links support. """ - parent = Parent.objects.create(name='parent') + parent = Parent.objects.create(name="parent") for i in range(1, 10): - Child.objects.create(id=i, name='child %s' % i, parent=parent, age=i) + Child.objects.create(id=i, name="child %s" % i, parent=parent, age=i) m = DynamicListDisplayLinksChildAdmin(Child, custom_site) - superuser = self._create_superuser('superuser') - request = self._mocked_authenticated_request('/child/', superuser) + superuser = self._create_superuser("superuser") + request = self._mocked_authenticated_request("/child/", superuser) response = m.changelist_view(request) for i in range(1, 10): - link = reverse('admin:admin_changelist_child_change', args=(i,)) + link = reverse("admin:admin_changelist_child_change", args=(i,)) self.assertContains(response, '%s' % (link, i)) list_display = m.get_list_display(request) list_display_links = m.get_list_display_links(request, list_display) - self.assertEqual(list_display, ('parent', 'name', 'age')) - self.assertEqual(list_display_links, ['age']) + self.assertEqual(list_display, ("parent", "name", "age")) + self.assertEqual(list_display_links, ["age"]) def test_no_list_display_links(self): """#15185 -- Allow no links from the 'change list' view grid.""" - p = Parent.objects.create(name='parent') + p = Parent.objects.create(name="parent") m = NoListDisplayLinksParentAdmin(Parent, custom_site) - superuser = self._create_superuser('superuser') - request = self._mocked_authenticated_request('/parent/', superuser) + superuser = self._create_superuser("superuser") + request = self._mocked_authenticated_request("/parent/", superuser) response = m.changelist_view(request) - link = reverse('admin:admin_changelist_parent_change', args=(p.pk,)) + link = reverse("admin:admin_changelist_parent_change", args=(p.pk,)) self.assertNotContains(response, '' % link) def test_clear_all_filters_link(self): self.client.force_login(self.superuser) - url = reverse('admin:auth_user_changelist') + url = reverse("admin:auth_user_changelist") response = self.client.get(url) - self.assertNotContains(response, '✖ Clear all filters') + self.assertNotContains(response, "✖ Clear all filters") link = '✖ Clear all filters' for data, href in ( - ({'is_staff__exact': '0'}, '?'), + ({"is_staff__exact": "0"}, "?"), ( - {'is_staff__exact': '0', 'username__startswith': 'test'}, - '?username__startswith=test', + {"is_staff__exact": "0", "username__startswith": "test"}, + "?username__startswith=test", ), ( - {'is_staff__exact': '0', SEARCH_VAR: 'test'}, - '?%s=test' % SEARCH_VAR, + {"is_staff__exact": "0", SEARCH_VAR: "test"}, + "?%s=test" % SEARCH_VAR, ), ( - {'is_staff__exact': '0', IS_POPUP_VAR: 'id'}, - '?%s=id' % IS_POPUP_VAR, + {"is_staff__exact": "0", IS_POPUP_VAR: "id"}, + "?%s=id" % IS_POPUP_VAR, ), ): with self.subTest(data=data): @@ -874,19 +949,19 @@ class ChangeListTests(TestCase): def test_clear_all_filters_link_callable_filter(self): self.client.force_login(self.superuser) - url = reverse('admin:admin_changelist_band_changelist') + url = reverse("admin:admin_changelist_band_changelist") response = self.client.get(url) - self.assertNotContains(response, '✖ Clear all filters') + self.assertNotContains(response, "✖ Clear all filters") link = '✖ Clear all filters' for data, href in ( - ({'nr_of_members_partition': '5'}, '?'), + ({"nr_of_members_partition": "5"}, "?"), ( - {'nr_of_members_partition': 'more', 'name__startswith': 'test'}, - '?name__startswith=test', + {"nr_of_members_partition": "more", "name__startswith": "test"}, + "?name__startswith=test", ), ( - {'nr_of_members_partition': '5', IS_POPUP_VAR: 'id'}, - '?%s=id' % IS_POPUP_VAR, + {"nr_of_members_partition": "5", IS_POPUP_VAR: "id"}, + "?%s=id" % IS_POPUP_VAR, ), ): with self.subTest(data=data): @@ -895,28 +970,28 @@ class ChangeListTests(TestCase): def test_no_clear_all_filters_link(self): self.client.force_login(self.superuser) - url = reverse('admin:auth_user_changelist') - link = '>✖ Clear all filters' + url = reverse("admin:auth_user_changelist") + link = ">✖ Clear all filters" for data in ( - {SEARCH_VAR: 'test'}, - {ORDER_VAR: '-1'}, - {TO_FIELD_VAR: 'id'}, - {PAGE_VAR: '1'}, - {IS_POPUP_VAR: '1'}, - {'username__startswith': 'test'}, + {SEARCH_VAR: "test"}, + {ORDER_VAR: "-1"}, + {TO_FIELD_VAR: "id"}, + {PAGE_VAR: "1"}, + {IS_POPUP_VAR: "1"}, + {"username__startswith": "test"}, ): with self.subTest(data=data): response = self.client.get(url, data=data) self.assertNotContains(response, link) def test_tuple_list_display(self): - swallow = Swallow.objects.create(origin='Africa', load='12.34', speed='22.2') - swallow2 = Swallow.objects.create(origin='Africa', load='12.34', speed='22.2') + swallow = Swallow.objects.create(origin="Africa", load="12.34", speed="22.2") + swallow2 = Swallow.objects.create(origin="Africa", load="12.34", speed="22.2") swallow_o2o = SwallowOneToOne.objects.create(swallow=swallow2) model_admin = SwallowAdmin(Swallow, custom_site) - superuser = self._create_superuser('superuser') - request = self._mocked_authenticated_request('/swallow/', superuser) + superuser = self._create_superuser("superuser") + request = self._mocked_authenticated_request("/swallow/", superuser) response = model_admin.changelist_view(request) # just want to ensure it doesn't blow up during rendering self.assertContains(response, str(swallow.origin)) @@ -924,7 +999,9 @@ class ChangeListTests(TestCase): self.assertContains(response, str(swallow.speed)) # Reverse one-to-one relations should work. self.assertContains(response, '-') - self.assertContains(response, '%s' % swallow_o2o) + self.assertContains( + response, '%s' % swallow_o2o + ) def test_multiuser_edit(self): """ @@ -945,150 +1022,152 @@ class ChangeListTests(TestCase): # Setup the test to reflect the DB state after step 2 where User2 has # edited the first swallow object's speed from '4' to '1'. - a = Swallow.objects.create(origin='Swallow A', load=4, speed=1) - b = Swallow.objects.create(origin='Swallow B', load=2, speed=2) - c = Swallow.objects.create(origin='Swallow C', load=5, speed=5) - d = Swallow.objects.create(origin='Swallow D', load=9, speed=9) + a = Swallow.objects.create(origin="Swallow A", load=4, speed=1) + b = Swallow.objects.create(origin="Swallow B", load=2, speed=2) + c = Swallow.objects.create(origin="Swallow C", load=5, speed=5) + d = Swallow.objects.create(origin="Swallow D", load=9, speed=9) - superuser = self._create_superuser('superuser') + superuser = self._create_superuser("superuser") self.client.force_login(superuser) - changelist_url = reverse('admin:admin_changelist_swallow_changelist') + changelist_url = reverse("admin:admin_changelist_swallow_changelist") # Send the POST from User1 for step 3. It's still using the changelist # ordering from before User2's edits in step 2. data = { - 'form-TOTAL_FORMS': '3', - 'form-INITIAL_FORMS': '3', - 'form-MIN_NUM_FORMS': '0', - 'form-MAX_NUM_FORMS': '1000', - 'form-0-uuid': str(d.pk), - 'form-1-uuid': str(c.pk), - 'form-2-uuid': str(a.pk), - 'form-0-load': '9.0', - 'form-0-speed': '9.0', - 'form-1-load': '5.0', - 'form-1-speed': '5.0', - 'form-2-load': '5.0', - 'form-2-speed': '4.0', - '_save': 'Save', + "form-TOTAL_FORMS": "3", + "form-INITIAL_FORMS": "3", + "form-MIN_NUM_FORMS": "0", + "form-MAX_NUM_FORMS": "1000", + "form-0-uuid": str(d.pk), + "form-1-uuid": str(c.pk), + "form-2-uuid": str(a.pk), + "form-0-load": "9.0", + "form-0-speed": "9.0", + "form-1-load": "5.0", + "form-1-speed": "5.0", + "form-2-load": "5.0", + "form-2-speed": "4.0", + "_save": "Save", } - response = self.client.post(changelist_url, data, follow=True, extra={'o': '-2'}) + response = self.client.post( + changelist_url, data, follow=True, extra={"o": "-2"} + ) # The object User1 edited in step 3 is displayed on the changelist and # has the correct edits applied. - self.assertContains(response, '1 swallow was changed successfully.') + self.assertContains(response, "1 swallow was changed successfully.") self.assertContains(response, a.origin) a.refresh_from_db() - self.assertEqual(a.load, float(data['form-2-load'])) - self.assertEqual(a.speed, float(data['form-2-speed'])) + self.assertEqual(a.load, float(data["form-2-load"])) + self.assertEqual(a.speed, float(data["form-2-speed"])) b.refresh_from_db() self.assertEqual(b.load, 2) self.assertEqual(b.speed, 2) c.refresh_from_db() - self.assertEqual(c.load, float(data['form-1-load'])) - self.assertEqual(c.speed, float(data['form-1-speed'])) + self.assertEqual(c.load, float(data["form-1-load"])) + self.assertEqual(c.speed, float(data["form-1-speed"])) d.refresh_from_db() - self.assertEqual(d.load, float(data['form-0-load'])) - self.assertEqual(d.speed, float(data['form-0-speed'])) + self.assertEqual(d.load, float(data["form-0-load"])) + self.assertEqual(d.speed, float(data["form-0-speed"])) # No new swallows were created. self.assertEqual(len(Swallow.objects.all()), 4) def test_get_edited_object_ids(self): - a = Swallow.objects.create(origin='Swallow A', load=4, speed=1) - b = Swallow.objects.create(origin='Swallow B', load=2, speed=2) - c = Swallow.objects.create(origin='Swallow C', load=5, speed=5) - superuser = self._create_superuser('superuser') + a = Swallow.objects.create(origin="Swallow A", load=4, speed=1) + b = Swallow.objects.create(origin="Swallow B", load=2, speed=2) + c = Swallow.objects.create(origin="Swallow C", load=5, speed=5) + superuser = self._create_superuser("superuser") self.client.force_login(superuser) - changelist_url = reverse('admin:admin_changelist_swallow_changelist') + changelist_url = reverse("admin:admin_changelist_swallow_changelist") m = SwallowAdmin(Swallow, custom_site) data = { - 'form-TOTAL_FORMS': '3', - 'form-INITIAL_FORMS': '3', - 'form-MIN_NUM_FORMS': '0', - 'form-MAX_NUM_FORMS': '1000', - 'form-0-uuid': str(a.pk), - 'form-1-uuid': str(b.pk), - 'form-2-uuid': str(c.pk), - 'form-0-load': '9.0', - 'form-0-speed': '9.0', - 'form-1-load': '5.0', - 'form-1-speed': '5.0', - 'form-2-load': '5.0', - 'form-2-speed': '4.0', - '_save': 'Save', + "form-TOTAL_FORMS": "3", + "form-INITIAL_FORMS": "3", + "form-MIN_NUM_FORMS": "0", + "form-MAX_NUM_FORMS": "1000", + "form-0-uuid": str(a.pk), + "form-1-uuid": str(b.pk), + "form-2-uuid": str(c.pk), + "form-0-load": "9.0", + "form-0-speed": "9.0", + "form-1-load": "5.0", + "form-1-speed": "5.0", + "form-2-load": "5.0", + "form-2-speed": "4.0", + "_save": "Save", } request = self.factory.post(changelist_url, data=data) - pks = m._get_edited_object_pks(request, prefix='form') + pks = m._get_edited_object_pks(request, prefix="form") self.assertEqual(sorted(pks), sorted([str(a.pk), str(b.pk), str(c.pk)])) def test_get_list_editable_queryset(self): - a = Swallow.objects.create(origin='Swallow A', load=4, speed=1) - Swallow.objects.create(origin='Swallow B', load=2, speed=2) + a = Swallow.objects.create(origin="Swallow A", load=4, speed=1) + Swallow.objects.create(origin="Swallow B", load=2, speed=2) data = { - 'form-TOTAL_FORMS': '2', - 'form-INITIAL_FORMS': '2', - 'form-MIN_NUM_FORMS': '0', - 'form-MAX_NUM_FORMS': '1000', - 'form-0-uuid': str(a.pk), - 'form-0-load': '10', - '_save': 'Save', + "form-TOTAL_FORMS": "2", + "form-INITIAL_FORMS": "2", + "form-MIN_NUM_FORMS": "0", + "form-MAX_NUM_FORMS": "1000", + "form-0-uuid": str(a.pk), + "form-0-load": "10", + "_save": "Save", } - superuser = self._create_superuser('superuser') + superuser = self._create_superuser("superuser") self.client.force_login(superuser) - changelist_url = reverse('admin:admin_changelist_swallow_changelist') + changelist_url = reverse("admin:admin_changelist_swallow_changelist") m = SwallowAdmin(Swallow, custom_site) request = self.factory.post(changelist_url, data=data) - queryset = m._get_list_editable_queryset(request, prefix='form') + queryset = m._get_list_editable_queryset(request, prefix="form") self.assertEqual(queryset.count(), 1) - data['form-0-uuid'] = 'INVALD_PRIMARY_KEY' + data["form-0-uuid"] = "INVALD_PRIMARY_KEY" # The unfiltered queryset is returned if there's invalid data. request = self.factory.post(changelist_url, data=data) - queryset = m._get_list_editable_queryset(request, prefix='form') + queryset = m._get_list_editable_queryset(request, prefix="form") self.assertEqual(queryset.count(), 2) def test_get_list_editable_queryset_with_regex_chars_in_prefix(self): - a = Swallow.objects.create(origin='Swallow A', load=4, speed=1) - Swallow.objects.create(origin='Swallow B', load=2, speed=2) + a = Swallow.objects.create(origin="Swallow A", load=4, speed=1) + Swallow.objects.create(origin="Swallow B", load=2, speed=2) data = { - 'form$-TOTAL_FORMS': '2', - 'form$-INITIAL_FORMS': '2', - 'form$-MIN_NUM_FORMS': '0', - 'form$-MAX_NUM_FORMS': '1000', - 'form$-0-uuid': str(a.pk), - 'form$-0-load': '10', - '_save': 'Save', + "form$-TOTAL_FORMS": "2", + "form$-INITIAL_FORMS": "2", + "form$-MIN_NUM_FORMS": "0", + "form$-MAX_NUM_FORMS": "1000", + "form$-0-uuid": str(a.pk), + "form$-0-load": "10", + "_save": "Save", } - superuser = self._create_superuser('superuser') + superuser = self._create_superuser("superuser") self.client.force_login(superuser) - changelist_url = reverse('admin:admin_changelist_swallow_changelist') + changelist_url = reverse("admin:admin_changelist_swallow_changelist") m = SwallowAdmin(Swallow, custom_site) request = self.factory.post(changelist_url, data=data) - queryset = m._get_list_editable_queryset(request, prefix='form$') + queryset = m._get_list_editable_queryset(request, prefix="form$") self.assertEqual(queryset.count(), 1) def test_changelist_view_list_editable_changed_objects_uses_filter(self): """list_editable edits use a filtered queryset to limit memory usage.""" - a = Swallow.objects.create(origin='Swallow A', load=4, speed=1) - Swallow.objects.create(origin='Swallow B', load=2, speed=2) + a = Swallow.objects.create(origin="Swallow A", load=4, speed=1) + Swallow.objects.create(origin="Swallow B", load=2, speed=2) data = { - 'form-TOTAL_FORMS': '2', - 'form-INITIAL_FORMS': '2', - 'form-MIN_NUM_FORMS': '0', - 'form-MAX_NUM_FORMS': '1000', - 'form-0-uuid': str(a.pk), - 'form-0-load': '10', - '_save': 'Save', + "form-TOTAL_FORMS": "2", + "form-INITIAL_FORMS": "2", + "form-MIN_NUM_FORMS": "0", + "form-MAX_NUM_FORMS": "1000", + "form-0-uuid": str(a.pk), + "form-0-load": "10", + "_save": "Save", } - superuser = self._create_superuser('superuser') + superuser = self._create_superuser("superuser") self.client.force_login(superuser) - changelist_url = reverse('admin:admin_changelist_swallow_changelist') + changelist_url = reverse("admin:admin_changelist_swallow_changelist") with CaptureQueriesContext(connection) as context: response = self.client.post(changelist_url, data=data) self.assertEqual(response.status_code, 200) - self.assertIn('WHERE', context.captured_queries[4]['sql']) - self.assertIn('IN', context.captured_queries[4]['sql']) + self.assertIn("WHERE", context.captured_queries[4]["sql"]) + self.assertIn("IN", context.captured_queries[4]["sql"]) # Check only the first few characters since the UUID may have dashes. - self.assertIn(str(a.pk)[:8], context.captured_queries[4]['sql']) + self.assertIn(str(a.pk)[:8], context.captured_queries[4]["sql"]) def test_deterministic_order_for_unordered_model(self): """ @@ -1096,7 +1175,7 @@ class ChangeListTests(TestCase): guarantee a deterministic order, even when the model doesn't have any default ordering defined (#17198). """ - superuser = self._create_superuser('superuser') + superuser = self._create_superuser("superuser") for counter in range(1, 51): UnorderedObject.objects.create(id=counter, bool=True) @@ -1109,9 +1188,11 @@ class ChangeListTests(TestCase): model_admin = UnorderedObjectAdmin(UnorderedObject, custom_site) counter = 0 if ascending else 51 for page in range(1, 6): - request = self._mocked_authenticated_request('/unorderedobject/?p=%s' % page, superuser) + request = self._mocked_authenticated_request( + "/unorderedobject/?p=%s" % page, superuser + ) response = model_admin.changelist_view(request) - for result in response.context_data['cl'].result_list: + for result in response.context_data["cl"].result_list: counter += 1 if ascending else -1 self.assertEqual(result.id, counter) custom_site.unregister(UnorderedObject) @@ -1121,17 +1202,17 @@ class ChangeListTests(TestCase): # When an order field is defined but multiple records have the same # value for that field, make sure everything gets ordered by -pk as well. - UnorderedObjectAdmin.ordering = ['bool'] + UnorderedObjectAdmin.ordering = ["bool"] check_results_order() # When order fields are defined, including the pk itself, use them. - UnorderedObjectAdmin.ordering = ['bool', '-pk'] + UnorderedObjectAdmin.ordering = ["bool", "-pk"] check_results_order() - UnorderedObjectAdmin.ordering = ['bool', 'pk'] + UnorderedObjectAdmin.ordering = ["bool", "pk"] check_results_order(ascending=True) - UnorderedObjectAdmin.ordering = ['-id', 'bool'] + UnorderedObjectAdmin.ordering = ["-id", "bool"] check_results_order() - UnorderedObjectAdmin.ordering = ['id', 'bool'] + UnorderedObjectAdmin.ordering = ["id", "bool"] check_results_order(ascending=True) def test_deterministic_order_for_model_ordered_by_its_manager(self): @@ -1140,7 +1221,7 @@ class ChangeListTests(TestCase): guarantee a deterministic order, even when the model has a manager that defines a default ordering (#17198). """ - superuser = self._create_superuser('superuser') + superuser = self._create_superuser("superuser") for counter in range(1, 51): OrderedObject.objects.create(id=counter, bool=True, number=counter) @@ -1153,9 +1234,11 @@ class ChangeListTests(TestCase): model_admin = OrderedObjectAdmin(OrderedObject, custom_site) counter = 0 if ascending else 51 for page in range(1, 6): - request = self._mocked_authenticated_request('/orderedobject/?p=%s' % page, superuser) + request = self._mocked_authenticated_request( + "/orderedobject/?p=%s" % page, superuser + ) response = model_admin.changelist_view(request) - for result in response.context_data['cl'].result_list: + for result in response.context_data["cl"].result_list: counter += 1 if ascending else -1 self.assertEqual(result.id, counter) custom_site.unregister(OrderedObject) @@ -1165,26 +1248,26 @@ class ChangeListTests(TestCase): # When an order field is defined but multiple records have the same # value for that field, make sure everything gets ordered by -pk as well. - OrderedObjectAdmin.ordering = ['bool'] + OrderedObjectAdmin.ordering = ["bool"] check_results_order() # When order fields are defined, including the pk itself, use them. - OrderedObjectAdmin.ordering = ['bool', '-pk'] + OrderedObjectAdmin.ordering = ["bool", "-pk"] check_results_order() - OrderedObjectAdmin.ordering = ['bool', 'pk'] + OrderedObjectAdmin.ordering = ["bool", "pk"] check_results_order(ascending=True) - OrderedObjectAdmin.ordering = ['-id', 'bool'] + OrderedObjectAdmin.ordering = ["-id", "bool"] check_results_order() - OrderedObjectAdmin.ordering = ['id', 'bool'] + OrderedObjectAdmin.ordering = ["id", "bool"] check_results_order(ascending=True) - @isolate_apps('admin_changelist') + @isolate_apps("admin_changelist") def test_total_ordering_optimization(self): class Related(models.Model): unique_field = models.BooleanField(unique=True) class Meta: - ordering = ('unique_field',) + ordering = ("unique_field",) class Model(models.Model): unique_field = models.BooleanField(unique=True) @@ -1198,64 +1281,69 @@ class ChangeListTests(TestCase): class Meta: unique_together = { - ('field', 'other_field'), - ('field', 'null_field'), - ('related', 'other_related_id'), + ("field", "other_field"), + ("field", "null_field"), + ("related", "other_related_id"), } class ModelAdmin(admin.ModelAdmin): def get_queryset(self, request): return Model.objects.none() - request = self._mocked_authenticated_request('/', self.superuser) - site = admin.AdminSite(name='admin') + request = self._mocked_authenticated_request("/", self.superuser) + site = admin.AdminSite(name="admin") model_admin = ModelAdmin(Model, site) change_list = model_admin.get_changelist_instance(request) tests = ( - ([], ['-pk']), + ([], ["-pk"]), # Unique non-nullable field. - (['unique_field'], ['unique_field']), - (['-unique_field'], ['-unique_field']), + (["unique_field"], ["unique_field"]), + (["-unique_field"], ["-unique_field"]), # Unique nullable field. - (['unique_nullable_field'], ['unique_nullable_field', '-pk']), + (["unique_nullable_field"], ["unique_nullable_field", "-pk"]), # Field. - (['field'], ['field', '-pk']), + (["field"], ["field", "-pk"]), # Related field introspection is not implemented. - (['related__unique_field'], ['related__unique_field', '-pk']), + (["related__unique_field"], ["related__unique_field", "-pk"]), # Related attname unique. - (['related_unique_id'], ['related_unique_id']), + (["related_unique_id"], ["related_unique_id"]), # Related ordering introspection is not implemented. - (['related_unique'], ['related_unique', '-pk']), + (["related_unique"], ["related_unique", "-pk"]), # Composite unique. - (['field', '-other_field'], ['field', '-other_field']), + (["field", "-other_field"], ["field", "-other_field"]), # Composite unique nullable. - (['-field', 'null_field'], ['-field', 'null_field', '-pk']), + (["-field", "null_field"], ["-field", "null_field", "-pk"]), # Composite unique and nullable. - (['-field', 'null_field', 'other_field'], ['-field', 'null_field', 'other_field']), + ( + ["-field", "null_field", "other_field"], + ["-field", "null_field", "other_field"], + ), # Composite unique attnames. - (['related_id', '-other_related_id'], ['related_id', '-other_related_id']), + (["related_id", "-other_related_id"], ["related_id", "-other_related_id"]), # Composite unique names. - (['related', '-other_related_id'], ['related', '-other_related_id', '-pk']), + (["related", "-other_related_id"], ["related", "-other_related_id", "-pk"]), ) # F() objects composite unique. - total_ordering = [F('field'), F('other_field').desc(nulls_last=True)] + total_ordering = [F("field"), F("other_field").desc(nulls_last=True)] # F() objects composite unique nullable. - non_total_ordering = [F('field'), F('null_field').desc(nulls_last=True)] + non_total_ordering = [F("field"), F("null_field").desc(nulls_last=True)] tests += ( (total_ordering, total_ordering), - (non_total_ordering, non_total_ordering + ['-pk']), + (non_total_ordering, non_total_ordering + ["-pk"]), ) for ordering, expected in tests: with self.subTest(ordering=ordering): - self.assertEqual(change_list._get_deterministic_ordering(ordering), expected) + self.assertEqual( + change_list._get_deterministic_ordering(ordering), expected + ) - @isolate_apps('admin_changelist') + @isolate_apps("admin_changelist") def test_total_ordering_optimization_meta_constraints(self): class Related(models.Model): unique_field = models.BooleanField(unique=True) class Meta: - ordering = ('unique_field',) + ordering = ("unique_field",) class Model(models.Model): field_1 = models.BooleanField() @@ -1274,28 +1362,28 @@ class ChangeListTests(TestCase): class Meta: constraints = [ *[ - models.UniqueConstraint(fields=fields, name=''.join(fields)) + models.UniqueConstraint(fields=fields, name="".join(fields)) for fields in ( - ['field_1'], - ['nullable_1'], - ['related_1'], - ['related_2_id'], - ['field_2', 'field_3'], - ['field_2', 'nullable_2'], - ['field_2', 'related_3'], - ['field_3', 'related_4_id'], + ["field_1"], + ["nullable_1"], + ["related_1"], + ["related_2_id"], + ["field_2", "field_3"], + ["field_2", "nullable_2"], + ["field_2", "related_3"], + ["field_3", "related_4_id"], ) ], - models.CheckConstraint(check=models.Q(id__gt=0), name='foo'), + models.CheckConstraint(check=models.Q(id__gt=0), name="foo"), models.UniqueConstraint( - fields=['field_5'], + fields=["field_5"], condition=models.Q(id__gt=10), - name='total_ordering_1', + name="total_ordering_1", ), models.UniqueConstraint( - fields=['field_6'], + fields=["field_6"], condition=models.Q(), - name='total_ordering', + name="total_ordering", ), ] @@ -1303,73 +1391,77 @@ class ChangeListTests(TestCase): def get_queryset(self, request): return Model.objects.none() - request = self._mocked_authenticated_request('/', self.superuser) - site = admin.AdminSite(name='admin') + request = self._mocked_authenticated_request("/", self.superuser) + site = admin.AdminSite(name="admin") model_admin = ModelAdmin(Model, site) change_list = model_admin.get_changelist_instance(request) tests = ( # Unique non-nullable field. - (['field_1'], ['field_1']), + (["field_1"], ["field_1"]), # Unique nullable field. - (['nullable_1'], ['nullable_1', '-pk']), + (["nullable_1"], ["nullable_1", "-pk"]), # Related attname unique. - (['related_1_id'], ['related_1_id']), - (['related_2_id'], ['related_2_id']), + (["related_1_id"], ["related_1_id"]), + (["related_2_id"], ["related_2_id"]), # Related ordering introspection is not implemented. - (['related_1'], ['related_1', '-pk']), + (["related_1"], ["related_1", "-pk"]), # Composite unique. - (['-field_2', 'field_3'], ['-field_2', 'field_3']), + (["-field_2", "field_3"], ["-field_2", "field_3"]), # Composite unique nullable. - (['field_2', '-nullable_2'], ['field_2', '-nullable_2', '-pk']), + (["field_2", "-nullable_2"], ["field_2", "-nullable_2", "-pk"]), # Composite unique and nullable. ( - ['field_2', '-nullable_2', 'field_3'], - ['field_2', '-nullable_2', 'field_3'], + ["field_2", "-nullable_2", "field_3"], + ["field_2", "-nullable_2", "field_3"], ), # Composite field and related field name. - (['field_2', '-related_3'], ['field_2', '-related_3', '-pk']), - (['field_3', 'related_4'], ['field_3', 'related_4', '-pk']), + (["field_2", "-related_3"], ["field_2", "-related_3", "-pk"]), + (["field_3", "related_4"], ["field_3", "related_4", "-pk"]), # Composite field and related field attname. - (['field_2', 'related_3_id'], ['field_2', 'related_3_id']), - (['field_3', '-related_4_id'], ['field_3', '-related_4_id']), + (["field_2", "related_3_id"], ["field_2", "related_3_id"]), + (["field_3", "-related_4_id"], ["field_3", "-related_4_id"]), # Partial unique constraint is ignored. - (['field_5'], ['field_5', '-pk']), + (["field_5"], ["field_5", "-pk"]), # Unique constraint with an empty condition. - (['field_6'], ['field_6']), + (["field_6"], ["field_6"]), ) for ordering, expected in tests: with self.subTest(ordering=ordering): - self.assertEqual(change_list._get_deterministic_ordering(ordering), expected) + self.assertEqual( + change_list._get_deterministic_ordering(ordering), expected + ) def test_dynamic_list_filter(self): """ Regression tests for ticket #17646: dynamic list_filter support. """ - parent = Parent.objects.create(name='parent') + parent = Parent.objects.create(name="parent") for i in range(10): - Child.objects.create(name='child %s' % i, parent=parent) + Child.objects.create(name="child %s" % i, parent=parent) - user_noparents = self._create_superuser('noparents') - user_parents = self._create_superuser('parents') + user_noparents = self._create_superuser("noparents") + user_parents = self._create_superuser("parents") # Test with user 'noparents' m = DynamicListFilterChildAdmin(Child, custom_site) - request = self._mocked_authenticated_request('/child/', user_noparents) + request = self._mocked_authenticated_request("/child/", user_noparents) response = m.changelist_view(request) - self.assertEqual(response.context_data['cl'].list_filter, ['name', 'age']) + self.assertEqual(response.context_data["cl"].list_filter, ["name", "age"]) # Test with user 'parents' m = DynamicListFilterChildAdmin(Child, custom_site) - request = self._mocked_authenticated_request('/child/', user_parents) + request = self._mocked_authenticated_request("/child/", user_parents) response = m.changelist_view(request) - self.assertEqual(response.context_data['cl'].list_filter, ('parent', 'name', 'age')) + self.assertEqual( + response.context_data["cl"].list_filter, ("parent", "name", "age") + ) def test_dynamic_search_fields(self): - child = self._create_superuser('child') + child = self._create_superuser("child") m = DynamicSearchFieldsChildAdmin(Child, custom_site) - request = self._mocked_authenticated_request('/child/', child) + request = self._mocked_authenticated_request("/child/", child) response = m.changelist_view(request) - self.assertEqual(response.context_data['cl'].search_fields, ('name', 'age')) + self.assertEqual(response.context_data["cl"].search_fields, ("name", "age")) def test_pagination_page_range(self): """ @@ -1378,7 +1470,7 @@ class ChangeListTests(TestCase): """ # instantiating and setting up ChangeList object m = GroupAdmin(Group, custom_site) - request = self.factory.get('/group/') + request = self.factory.get("/group/") request.user = self.superuser cl = m.get_changelist_instance(request) cl.list_per_page = 10 @@ -1401,144 +1493,148 @@ class ChangeListTests(TestCase): # assuming exactly `pages * cl.list_per_page` objects Group.objects.all().delete() for i in range(pages * cl.list_per_page): - Group.objects.create(name='test band') + Group.objects.create(name="test band") # setting page number and calculating page range cl.page_num = number cl.get_results(request) - self.assertEqual(list(pagination(cl)['page_range']), expected) + self.assertEqual(list(pagination(cl)["page_range"]), expected) def test_object_tools_displayed_no_add_permission(self): """ When ModelAdmin.has_add_permission() returns False, the object-tools block is still shown. """ - superuser = self._create_superuser('superuser') + superuser = self._create_superuser("superuser") m = EventAdmin(Event, custom_site) - request = self._mocked_authenticated_request('/event/', superuser) + request = self._mocked_authenticated_request("/event/", superuser) self.assertFalse(m.has_add_permission(request)) response = m.changelist_view(request) self.assertIn('", ) def test_no_parent_callable_lookup(self): """Admin inline `readonly_field` shouldn't invoke parent ModelAdmin callable""" # Identically named callable isn't present in the parent ModelAdmin, # rendering of the add view shouldn't explode - response = self.client.get(reverse('admin:admin_inlines_novel_add')) + response = self.client.get(reverse("admin:admin_inlines_novel_add")) # View should have the child inlines section self.assertContains( response, - '
Callable in QuestionInline

') + self.assertContains(response, "

Callable in QuestionInline

") def test_help_text(self): """ The inlines' model field help texts are displayed when using both the stacked and tabular layouts. """ - response = self.client.get(reverse('admin:admin_inlines_holder4_add')) - self.assertContains(response, '
Awesome stacked help text is awesome.
', 4) + response = self.client.get(reverse("admin:admin_inlines_holder4_add")) + self.assertContains( + response, '
Awesome stacked help text is awesome.
', 4 + ) self.assertContains( response, '', - 1 + 1, ) # ReadOnly fields - response = self.client.get(reverse('admin:admin_inlines_capofamiglia_add')) + response = self.client.get(reverse("admin:admin_inlines_capofamiglia_add")) self.assertContains( response, '', - 1 + 1, ) def test_tabular_model_form_meta_readonly_field(self): @@ -224,22 +269,24 @@ class TestInline(TestDataMixin, TestCase): Tabular inlines use ModelForm.Meta.help_texts and labels for read-only fields. """ - response = self.client.get(reverse('admin:admin_inlines_someparentmodel_add')) + response = self.client.get(reverse("admin:admin_inlines_someparentmodel_add")) self.assertContains( response, '' + 'title="Help text from ModelForm.Meta">', ) - self.assertContains(response, 'Label from ModelForm.Meta') + self.assertContains(response, "Label from ModelForm.Meta") def test_inline_hidden_field_no_column(self): """#18263 -- Make sure hidden fields don't get a column in tabular inlines""" - parent = SomeParentModel.objects.create(name='a') - SomeChildModel.objects.create(name='b', position='0', parent=parent) - SomeChildModel.objects.create(name='c', position='1', parent=parent) - response = self.client.get(reverse('admin:admin_inlines_someparentmodel_change', args=(parent.pk,))) + parent = SomeParentModel.objects.create(name="a") + SomeChildModel.objects.create(name="b", position="0", parent=parent) + SomeChildModel.objects.create(name="c", position="1", parent=parent) + response = self.client.get( + reverse("admin:admin_inlines_someparentmodel_change", args=(parent.pk,)) + ) self.assertNotContains(response, '') self.assertInHTML( 'Position', response.rendered_content) - self.assertInHTML('

0

', response.rendered_content) - self.assertInHTML('

1

', response.rendered_content) + self.assertInHTML( + 'Position', + response.rendered_content, + ) + self.assertInHTML( + '

0

', response.rendered_content + ) + self.assertInHTML( + '

1

', response.rendered_content + ) def test_stacked_inline_hidden_field_with_view_only_permissions(self): """ @@ -269,12 +323,14 @@ class TestInline(TestDataMixin, TestCase): """ self.client.force_login(self.view_only_user) url = reverse( - 'stacked_inline_hidden_field_in_group_admin:admin_inlines_someparentmodel_change', + "stacked_inline_hidden_field_in_group_admin:admin_inlines_someparentmodel_change", args=(self.parent.pk,), ) response = self.client.get(url) # The whole line containing name + position fields is not hidden. - self.assertContains(response, '
') + self.assertContains( + response, '
' + ) # The div containing the position field is hidden. self.assertInHTML( '