wbcore 2.2.1__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- wbcore/__init__.py +1 -0
- wbcore/admin.py +197 -0
- wbcore/apps.py +17 -0
- wbcore/cache/__init__.py +0 -0
- wbcore/cache/buttons.py +22 -0
- wbcore/cache/decorators.py +29 -0
- wbcore/cache/mixins.py +48 -0
- wbcore/cache/registry.py +90 -0
- wbcore/cache/views.py +18 -0
- wbcore/configs/__init__.py +11 -0
- wbcore/configs/configs.py +51 -0
- wbcore/configs/decorators.py +11 -0
- wbcore/configs/registry.py +35 -0
- wbcore/configs/views.py +11 -0
- wbcore/configurations/__init__.py +1 -0
- wbcore/configurations/base.py +45 -0
- wbcore/configurations/configurations/__init__.py +16 -0
- wbcore/configurations/configurations/apps.py +54 -0
- wbcore/configurations/configurations/authentication.py +43 -0
- wbcore/configurations/configurations/base.py +15 -0
- wbcore/configurations/configurations/cache.py +20 -0
- wbcore/configurations/configurations/celery.py +26 -0
- wbcore/configurations/configurations/i18nl10n.py +10 -0
- wbcore/configurations/configurations/mail.py +2 -0
- wbcore/configurations/configurations/maintenance.py +53 -0
- wbcore/configurations/configurations/media.py +22 -0
- wbcore/configurations/configurations/middleware.py +27 -0
- wbcore/configurations/configurations/network.py +19 -0
- wbcore/configurations/configurations/rest_framework.py +42 -0
- wbcore/configurations/configurations/static.py +28 -0
- wbcore/configurations/configurations/templates.py +17 -0
- wbcore/configurations/configurations/uvicorn.py +9 -0
- wbcore/configurations/configurations/wbcore.py +68 -0
- wbcore/content_type/__init__.py +0 -0
- wbcore/content_type/admin.py +8 -0
- wbcore/content_type/filters.py +19 -0
- wbcore/content_type/serializers.py +89 -0
- wbcore/content_type/utils.py +30 -0
- wbcore/content_type/viewsets.py +80 -0
- wbcore/contrib/__init__.py +0 -0
- wbcore/contrib/agenda/__init__.py +0 -0
- wbcore/contrib/agenda/admin/__init__.py +2 -0
- wbcore/contrib/agenda/admin/calendar_item.py +13 -0
- wbcore/contrib/agenda/admin/conference_room.py +18 -0
- wbcore/contrib/agenda/apps.py +6 -0
- wbcore/contrib/agenda/configurations.py +11 -0
- wbcore/contrib/agenda/factories/__init__.py +2 -0
- wbcore/contrib/agenda/factories/calendar_item.py +47 -0
- wbcore/contrib/agenda/factories/conference_room.py +19 -0
- wbcore/contrib/agenda/filters/__init__.py +2 -0
- wbcore/contrib/agenda/filters/calendar_item.py +64 -0
- wbcore/contrib/agenda/filters/conference_room.py +41 -0
- wbcore/contrib/agenda/migrations/0001_initial.py +84 -0
- wbcore/contrib/agenda/migrations/0002_initial.py +26 -0
- wbcore/contrib/agenda/migrations/0003_calendaritem_endpoint_basename.py +42 -0
- wbcore/contrib/agenda/migrations/0004_alter_calendaritem_item_type.py +17 -0
- wbcore/contrib/agenda/migrations/0005_building_and_more.py +94 -0
- wbcore/contrib/agenda/migrations/0006_calendaritem_is_deletable.py +17 -0
- wbcore/contrib/agenda/migrations/0007_alter_calendaritem_options.py +21 -0
- wbcore/contrib/agenda/migrations/0008_alter_calendaritem_item_type.py +17 -0
- wbcore/contrib/agenda/migrations/0009_alter_calendaritem_icon.py +18 -0
- wbcore/contrib/agenda/migrations/__init__.py +0 -0
- wbcore/contrib/agenda/models/__init__.py +2 -0
- wbcore/contrib/agenda/models/calendar_item.py +238 -0
- wbcore/contrib/agenda/models/conference_room.py +95 -0
- wbcore/contrib/agenda/release_notes/1_0_0.md +13 -0
- wbcore/contrib/agenda/release_notes/__init__.py +0 -0
- wbcore/contrib/agenda/serializers/__init__.py +10 -0
- wbcore/contrib/agenda/serializers/calendar_item.py +76 -0
- wbcore/contrib/agenda/serializers/conference_room.py +98 -0
- wbcore/contrib/agenda/signals.py +8 -0
- wbcore/contrib/agenda/tests/__init__.py +0 -0
- wbcore/contrib/agenda/tests/conftest.py +14 -0
- wbcore/contrib/agenda/tests/signals.py +16 -0
- wbcore/contrib/agenda/tests/test_models.py +34 -0
- wbcore/contrib/agenda/tests/test_viewsets.py +171 -0
- wbcore/contrib/agenda/tests/tests.py +25 -0
- wbcore/contrib/agenda/typings.py +19 -0
- wbcore/contrib/agenda/urls.py +25 -0
- wbcore/contrib/agenda/viewsets/__init__.py +13 -0
- wbcore/contrib/agenda/viewsets/buttons/__init__.py +1 -0
- wbcore/contrib/agenda/viewsets/buttons/conference_room.py +20 -0
- wbcore/contrib/agenda/viewsets/calendar_items.py +168 -0
- wbcore/contrib/agenda/viewsets/conference_room.py +48 -0
- wbcore/contrib/agenda/viewsets/display/__init__.py +2 -0
- wbcore/contrib/agenda/viewsets/display/calendar_items.py +17 -0
- wbcore/contrib/agenda/viewsets/display/conference_room.py +41 -0
- wbcore/contrib/agenda/viewsets/endpoints/__init__.py +1 -0
- wbcore/contrib/agenda/viewsets/endpoints/calendar_items.py +18 -0
- wbcore/contrib/agenda/viewsets/menu/__init__.py +2 -0
- wbcore/contrib/agenda/viewsets/menu/calendar_items.py +17 -0
- wbcore/contrib/agenda/viewsets/menu/conference_room.py +37 -0
- wbcore/contrib/agenda/viewsets/titles/__init__.py +2 -0
- wbcore/contrib/agenda/viewsets/titles/calendar_items.py +7 -0
- wbcore/contrib/agenda/viewsets/titles/conference_room.py +24 -0
- wbcore/contrib/ai/__init__.py +0 -0
- wbcore/contrib/ai/apps.py +5 -0
- wbcore/contrib/ai/exceptions.py +42 -0
- wbcore/contrib/ai/llm/__init__.py +0 -0
- wbcore/contrib/ai/llm/config.py +107 -0
- wbcore/contrib/ai/llm/decorators.py +10 -0
- wbcore/contrib/ai/llm/mixins.py +35 -0
- wbcore/contrib/ai/llm/utils.py +45 -0
- wbcore/contrib/authentication/__init__.py +9 -0
- wbcore/contrib/authentication/admin.py +247 -0
- wbcore/contrib/authentication/apps.py +14 -0
- wbcore/contrib/authentication/authentication.py +162 -0
- wbcore/contrib/authentication/configs.py +9 -0
- wbcore/contrib/authentication/configurations.py +53 -0
- wbcore/contrib/authentication/dynamic_preferences_registry.py +26 -0
- wbcore/contrib/authentication/factories/__init__.py +3 -0
- wbcore/contrib/authentication/factories/tokens.py +15 -0
- wbcore/contrib/authentication/factories/users.py +82 -0
- wbcore/contrib/authentication/factories/users_activities.py +19 -0
- wbcore/contrib/authentication/filters.py +18 -0
- wbcore/contrib/authentication/management/__init__.py +14 -0
- wbcore/contrib/authentication/migrations/0001_initial_squashed.py +174 -0
- wbcore/contrib/authentication/migrations/0002_profile.py +26 -0
- wbcore/contrib/authentication/migrations/0003_alter_user_profile.py +34 -0
- wbcore/contrib/authentication/migrations/0004_token.py +51 -0
- wbcore/contrib/authentication/migrations/0005_user_external_calendar_settings.py +17 -0
- wbcore/contrib/authentication/migrations/0006_auto_20231206_1422.py +13 -0
- wbcore/contrib/authentication/migrations/__init__.py +0 -0
- wbcore/contrib/authentication/models/__init__.py +3 -0
- wbcore/contrib/authentication/models/tokens.py +140 -0
- wbcore/contrib/authentication/models/users.py +225 -0
- wbcore/contrib/authentication/models/users_activities.py +112 -0
- wbcore/contrib/authentication/release_notes/1_0_0.md +13 -0
- wbcore/contrib/authentication/release_notes/__init__.py +0 -0
- wbcore/contrib/authentication/serializers/__init__.py +14 -0
- wbcore/contrib/authentication/serializers/users.py +350 -0
- wbcore/contrib/authentication/serializers/users_activites.py +37 -0
- wbcore/contrib/authentication/tasks.py +29 -0
- wbcore/contrib/authentication/tests/__init__.py +0 -0
- wbcore/contrib/authentication/tests/conftest.py +18 -0
- wbcore/contrib/authentication/tests/e2e/__init__.py +1 -0
- wbcore/contrib/authentication/tests/e2e/e2e_auth_utility.py +20 -0
- wbcore/contrib/authentication/tests/signals.py +17 -0
- wbcore/contrib/authentication/tests/test_configs.py +6 -0
- wbcore/contrib/authentication/tests/test_serializers.py +6 -0
- wbcore/contrib/authentication/tests/test_tasks.py +33 -0
- wbcore/contrib/authentication/tests/test_tokens.py +126 -0
- wbcore/contrib/authentication/tests/test_users.py +338 -0
- wbcore/contrib/authentication/tests/test_viewsets.py +6 -0
- wbcore/contrib/authentication/tests/tests.py +15 -0
- wbcore/contrib/authentication/urls.py +97 -0
- wbcore/contrib/authentication/utils.py +10 -0
- wbcore/contrib/authentication/viewsets/__init__.py +19 -0
- wbcore/contrib/authentication/viewsets/buttons/__init__.py +1 -0
- wbcore/contrib/authentication/viewsets/buttons/users.py +55 -0
- wbcore/contrib/authentication/viewsets/display/__init__.py +6 -0
- wbcore/contrib/authentication/viewsets/display/user_activities.py +85 -0
- wbcore/contrib/authentication/viewsets/display/users.py +72 -0
- wbcore/contrib/authentication/viewsets/endpoints/__init__.py +6 -0
- wbcore/contrib/authentication/viewsets/endpoints/user_activities.py +22 -0
- wbcore/contrib/authentication/viewsets/endpoints/users.py +20 -0
- wbcore/contrib/authentication/viewsets/menu/__init__.py +6 -0
- wbcore/contrib/authentication/viewsets/menu/user_activities.py +39 -0
- wbcore/contrib/authentication/viewsets/menu/users.py +16 -0
- wbcore/contrib/authentication/viewsets/titles/__init__.py +12 -0
- wbcore/contrib/authentication/viewsets/titles/user_activities.py +31 -0
- wbcore/contrib/authentication/viewsets/titles/users.py +26 -0
- wbcore/contrib/authentication/viewsets/user_activities.py +222 -0
- wbcore/contrib/authentication/viewsets/users.py +328 -0
- wbcore/contrib/color/migrations/0001_initial.py +33 -0
- wbcore/contrib/color/migrations/0002_alter_colorgradient_colors.py +25 -0
- wbcore/contrib/color/migrations/__init__.py +0 -0
- wbcore/contrib/currency/__init__.py +0 -0
- wbcore/contrib/currency/admin.py +32 -0
- wbcore/contrib/currency/apps.py +5 -0
- wbcore/contrib/currency/dynamic_preferences_registry.py +39 -0
- wbcore/contrib/currency/factories.py +39 -0
- wbcore/contrib/currency/import_export/__init__.py +0 -0
- wbcore/contrib/currency/import_export/backends/__init__.py +1 -0
- wbcore/contrib/currency/import_export/backends/fixerio/__init__.py +1 -0
- wbcore/contrib/currency/import_export/backends/fixerio/currency_fx_rates.py +66 -0
- wbcore/contrib/currency/import_export/backends/utils.py +5 -0
- wbcore/contrib/currency/import_export/handlers/__init__.py +2 -0
- wbcore/contrib/currency/import_export/handlers/currency.py +24 -0
- wbcore/contrib/currency/import_export/handlers/currency_fx_rates.py +28 -0
- wbcore/contrib/currency/import_export/parsers/__init__.py +0 -0
- wbcore/contrib/currency/import_export/parsers/fixerio/__init__.py +0 -0
- wbcore/contrib/currency/import_export/parsers/fixerio/currency_fx_rates.py +34 -0
- wbcore/contrib/currency/migrations/0001_initial.py +89 -0
- wbcore/contrib/currency/migrations/__init__.py +0 -0
- wbcore/contrib/currency/models.py +176 -0
- wbcore/contrib/currency/release_notes/1_0_0.md +13 -0
- wbcore/contrib/currency/release_notes/__init__.py +0 -0
- wbcore/contrib/currency/serializers.py +40 -0
- wbcore/contrib/currency/tests/__init__.py +0 -0
- wbcore/contrib/currency/tests/conftest.py +7 -0
- wbcore/contrib/currency/tests/test_models.py +104 -0
- wbcore/contrib/currency/tests/test_serializers.py +62 -0
- wbcore/contrib/currency/tests/test_viewsets.py +197 -0
- wbcore/contrib/currency/urls.py +19 -0
- wbcore/contrib/currency/viewsets/__init__.py +2 -0
- wbcore/contrib/currency/viewsets/buttons/__init__.py +0 -0
- wbcore/contrib/currency/viewsets/currency.py +56 -0
- wbcore/contrib/currency/viewsets/currency_fx_rates.py +32 -0
- wbcore/contrib/currency/viewsets/display/__init__.py +2 -0
- wbcore/contrib/currency/viewsets/display/currency.py +37 -0
- wbcore/contrib/currency/viewsets/display/currency_fx_rates.py +9 -0
- wbcore/contrib/currency/viewsets/endpoints/__init__.py +1 -0
- wbcore/contrib/currency/viewsets/endpoints/currency_fx_rates.py +14 -0
- wbcore/contrib/currency/viewsets/menu/__init__.py +1 -0
- wbcore/contrib/currency/viewsets/menu/currency.py +8 -0
- wbcore/contrib/currency/viewsets/preview/__init__.py +1 -0
- wbcore/contrib/currency/viewsets/preview/currency.py +10 -0
- wbcore/contrib/currency/viewsets/titles/__init__.py +2 -0
- wbcore/contrib/currency/viewsets/titles/currency.py +6 -0
- wbcore/contrib/currency/viewsets/titles/currency_fx_rates.py +8 -0
- wbcore/contrib/dataloader/__init__.py +1 -0
- wbcore/contrib/dataloader/apps.py +5 -0
- wbcore/contrib/dataloader/dataloaders/__init__.py +2 -0
- wbcore/contrib/dataloader/dataloaders/dataloaders.py +24 -0
- wbcore/contrib/dataloader/dataloaders/proxies.py +81 -0
- wbcore/contrib/dataloader/models/__init__.py +1 -0
- wbcore/contrib/dataloader/models/entities.py +29 -0
- wbcore/contrib/dataloader/models/querysets/__init__.py +1 -0
- wbcore/contrib/dataloader/models/querysets/entities.py +27 -0
- wbcore/contrib/dataloader/tests/__init__.py +0 -0
- wbcore/contrib/dataloader/tests/conftest.py +26 -0
- wbcore/contrib/dataloader/tests/test/__init__.py +0 -0
- wbcore/contrib/dataloader/tests/test/dataloaders/__init__.py +0 -0
- wbcore/contrib/dataloader/tests/test/dataloaders/dataloaders.py +18 -0
- wbcore/contrib/dataloader/tests/test/dataloaders/protocols.py +6 -0
- wbcore/contrib/dataloader/tests/test/dataloaders/proxies.py +11 -0
- wbcore/contrib/dataloader/tests/test/factories.py +13 -0
- wbcore/contrib/dataloader/tests/test/models.py +10 -0
- wbcore/contrib/dataloader/tests/test_dataloaders.py +37 -0
- wbcore/contrib/dataloader/tests/test_entities.py +12 -0
- wbcore/contrib/dataloader/utils.py +17 -0
- wbcore/contrib/directory/__init__.py +0 -0
- wbcore/contrib/directory/admin/__init__.py +14 -0
- wbcore/contrib/directory/admin/contacts.py +54 -0
- wbcore/contrib/directory/admin/entries.py +230 -0
- wbcore/contrib/directory/admin/relationships.py +73 -0
- wbcore/contrib/directory/apps.py +6 -0
- wbcore/contrib/directory/configs.py +8 -0
- wbcore/contrib/directory/configurations.py +69 -0
- wbcore/contrib/directory/dynamic_preferences_registry.py +61 -0
- wbcore/contrib/directory/factories/__init__.py +34 -0
- wbcore/contrib/directory/factories/contacts.py +71 -0
- wbcore/contrib/directory/factories/entries.py +169 -0
- wbcore/contrib/directory/factories/relationships.py +77 -0
- wbcore/contrib/directory/filters/__init__.py +22 -0
- wbcore/contrib/directory/filters/contacts.py +233 -0
- wbcore/contrib/directory/filters/entries.py +247 -0
- wbcore/contrib/directory/filters/relationships.py +89 -0
- wbcore/contrib/directory/migrations/0001_initial.py +871 -0
- wbcore/contrib/directory/migrations/0002_auto_20230414_1553.py +42 -0
- wbcore/contrib/directory/migrations/0003_remove_entry_last_event.py +16 -0
- wbcore/contrib/directory/migrations/0004_entry_is_draft_entry.py +21 -0
- wbcore/contrib/directory/migrations/0005_entry_salutation.py +17 -0
- wbcore/contrib/directory/migrations/0006_employeremployeerelationship_position_name.py +23 -0
- wbcore/contrib/directory/migrations/0007_alter_bankingcontact_options.py +20 -0
- wbcore/contrib/directory/migrations/0008_bankingcontact_access.py +17 -0
- wbcore/contrib/directory/migrations/0009_remove_entry_external_identfier_and_more.py +22 -0
- wbcore/contrib/directory/migrations/__init__.py +0 -0
- wbcore/contrib/directory/models/__init__.py +27 -0
- wbcore/contrib/directory/models/contacts.py +554 -0
- wbcore/contrib/directory/models/entries.py +889 -0
- wbcore/contrib/directory/models/relationships.py +634 -0
- wbcore/contrib/directory/preferences.py +10 -0
- wbcore/contrib/directory/release_notes/1_0_0.md +13 -0
- wbcore/contrib/directory/release_notes/1_0_1.md +13 -0
- wbcore/contrib/directory/release_notes/__init__.py +0 -0
- wbcore/contrib/directory/serializers/__init__.py +63 -0
- wbcore/contrib/directory/serializers/companies.py +158 -0
- wbcore/contrib/directory/serializers/contacts.py +404 -0
- wbcore/contrib/directory/serializers/entries.py +344 -0
- wbcore/contrib/directory/serializers/entry_representations.py +35 -0
- wbcore/contrib/directory/serializers/persons.py +209 -0
- wbcore/contrib/directory/serializers/relationships.py +332 -0
- wbcore/contrib/directory/signals.py +3 -0
- wbcore/contrib/directory/tests/__init__.py +0 -0
- wbcore/contrib/directory/tests/conftest.py +60 -0
- wbcore/contrib/directory/tests/disable_signals.py +52 -0
- wbcore/contrib/directory/tests/e2e/__init__.py +7 -0
- wbcore/contrib/directory/tests/e2e/e2e_directory_utility.py +162 -0
- wbcore/contrib/directory/tests/signals.py +90 -0
- wbcore/contrib/directory/tests/test_configs.py +6 -0
- wbcore/contrib/directory/tests/test_filters.py +59 -0
- wbcore/contrib/directory/tests/test_models.py +285 -0
- wbcore/contrib/directory/tests/test_permissions.py +122 -0
- wbcore/contrib/directory/tests/test_serializers.py +201 -0
- wbcore/contrib/directory/tests/test_viewsets.py +677 -0
- wbcore/contrib/directory/tests/tests.py +130 -0
- wbcore/contrib/directory/typings.py +17 -0
- wbcore/contrib/directory/urls.py +135 -0
- wbcore/contrib/directory/viewsets/__init__.py +58 -0
- wbcore/contrib/directory/viewsets/buttons/__init__.py +7 -0
- wbcore/contrib/directory/viewsets/buttons/contacts.py +16 -0
- wbcore/contrib/directory/viewsets/buttons/entries.py +133 -0
- wbcore/contrib/directory/viewsets/buttons/relationships.py +31 -0
- wbcore/contrib/directory/viewsets/contacts.py +393 -0
- wbcore/contrib/directory/viewsets/display/__init__.py +36 -0
- wbcore/contrib/directory/viewsets/display/contacts.py +380 -0
- wbcore/contrib/directory/viewsets/display/entries.py +501 -0
- wbcore/contrib/directory/viewsets/display/relationships.py +315 -0
- wbcore/contrib/directory/viewsets/display/utils.py +33 -0
- wbcore/contrib/directory/viewsets/endpoints/__init__.py +22 -0
- wbcore/contrib/directory/viewsets/endpoints/contacts.py +54 -0
- wbcore/contrib/directory/viewsets/endpoints/entries.py +30 -0
- wbcore/contrib/directory/viewsets/endpoints/relationships.py +105 -0
- wbcore/contrib/directory/viewsets/entries.py +212 -0
- wbcore/contrib/directory/viewsets/menu/__init__.py +16 -0
- wbcore/contrib/directory/viewsets/menu/contacts.py +25 -0
- wbcore/contrib/directory/viewsets/menu/entries.py +61 -0
- wbcore/contrib/directory/viewsets/menu/relationships.py +31 -0
- wbcore/contrib/directory/viewsets/menu/utils.py +72 -0
- wbcore/contrib/directory/viewsets/mixins.py +11 -0
- wbcore/contrib/directory/viewsets/previews/__init__.py +2 -0
- wbcore/contrib/directory/viewsets/previews/contacts.py +18 -0
- wbcore/contrib/directory/viewsets/previews/entries.py +31 -0
- wbcore/contrib/directory/viewsets/relationships.py +241 -0
- wbcore/contrib/directory/viewsets/titles/__init__.py +30 -0
- wbcore/contrib/directory/viewsets/titles/contacts.py +122 -0
- wbcore/contrib/directory/viewsets/titles/entries.py +29 -0
- wbcore/contrib/directory/viewsets/titles/relationships.py +86 -0
- wbcore/contrib/directory/viewsets/titles/utils.py +46 -0
- wbcore/contrib/directory/viewsets/utils.py +101 -0
- wbcore/contrib/documents/__init__.py +0 -0
- wbcore/contrib/documents/admin.py +79 -0
- wbcore/contrib/documents/apps.py +6 -0
- wbcore/contrib/documents/factories.py +43 -0
- wbcore/contrib/documents/filters.py +82 -0
- wbcore/contrib/documents/migrations/0001_initial.py +189 -0
- wbcore/contrib/documents/migrations/0002_documentmodelrelationship_primary_and_more.py +22 -0
- wbcore/contrib/documents/migrations/0003_alter_documentmodelrelationship_unique_together_and_more.py +30 -0
- wbcore/contrib/documents/migrations/0004_auto_20240103_0958.py +44 -0
- wbcore/contrib/documents/migrations/0005_document_valid_from_document_valid_until_and_more.py +32 -0
- wbcore/contrib/documents/migrations/__init__.py +0 -0
- wbcore/contrib/documents/models/__init__.py +4 -0
- wbcore/contrib/documents/models/document_model_relationships.py +57 -0
- wbcore/contrib/documents/models/document_types.py +35 -0
- wbcore/contrib/documents/models/documents.py +309 -0
- wbcore/contrib/documents/models/mixins.py +10 -0
- wbcore/contrib/documents/models/shareable_links.py +90 -0
- wbcore/contrib/documents/release_notes/1_0_0.md +13 -0
- wbcore/contrib/documents/release_notes/__init__.py +0 -0
- wbcore/contrib/documents/serializers/__init__.py +12 -0
- wbcore/contrib/documents/serializers/document_model_relationships.py +31 -0
- wbcore/contrib/documents/serializers/document_types.py +40 -0
- wbcore/contrib/documents/serializers/documents.py +64 -0
- wbcore/contrib/documents/serializers/shareable_links.py +90 -0
- wbcore/contrib/documents/urls.py +42 -0
- wbcore/contrib/documents/viewsets/__init__.py +10 -0
- wbcore/contrib/documents/viewsets/buttons/__init__.py +3 -0
- wbcore/contrib/documents/viewsets/buttons/documents.py +53 -0
- wbcore/contrib/documents/viewsets/buttons/shareable_links.py +20 -0
- wbcore/contrib/documents/viewsets/buttons/signals.py +13 -0
- wbcore/contrib/documents/viewsets/display/__init__.py +4 -0
- wbcore/contrib/documents/viewsets/display/document_model_relationships.py +18 -0
- wbcore/contrib/documents/viewsets/display/document_types.py +23 -0
- wbcore/contrib/documents/viewsets/display/documents.py +101 -0
- wbcore/contrib/documents/viewsets/display/shareable_links.py +65 -0
- wbcore/contrib/documents/viewsets/document_model_relationships.py +25 -0
- wbcore/contrib/documents/viewsets/document_types.py +37 -0
- wbcore/contrib/documents/viewsets/documents.py +107 -0
- wbcore/contrib/documents/viewsets/endpoints/__init__.py +5 -0
- wbcore/contrib/documents/viewsets/endpoints/documents.py +19 -0
- wbcore/contrib/documents/viewsets/endpoints/documents_model_relationships.py +13 -0
- wbcore/contrib/documents/viewsets/endpoints/shareable_links.py +45 -0
- wbcore/contrib/documents/viewsets/menu/__init__.py +1 -0
- wbcore/contrib/documents/viewsets/menu/documents.py +24 -0
- wbcore/contrib/documents/viewsets/previews/__init__.py +1 -0
- wbcore/contrib/documents/viewsets/previews/documents.py +10 -0
- wbcore/contrib/documents/viewsets/shareable_links.py +109 -0
- wbcore/contrib/documents/viewsets/titles/__init__.py +3 -0
- wbcore/contrib/documents/viewsets/titles/document_types.py +13 -0
- wbcore/contrib/documents/viewsets/titles/documents.py +26 -0
- wbcore/contrib/documents/viewsets/titles/shareable_links.py +13 -0
- wbcore/contrib/dynamic_preferences/__init__.py +0 -0
- wbcore/contrib/dynamic_preferences/types.py +19 -0
- wbcore/contrib/example_app/__init__.py +0 -0
- wbcore/contrib/example_app/admin.py +117 -0
- wbcore/contrib/example_app/apps.py +6 -0
- wbcore/contrib/example_app/factories/__init__.py +8 -0
- wbcore/contrib/example_app/factories/event.py +26 -0
- wbcore/contrib/example_app/factories/league.py +15 -0
- wbcore/contrib/example_app/factories/match.py +25 -0
- wbcore/contrib/example_app/factories/person.py +32 -0
- wbcore/contrib/example_app/factories/role.py +9 -0
- wbcore/contrib/example_app/factories/sport.py +12 -0
- wbcore/contrib/example_app/factories/stadium.py +12 -0
- wbcore/contrib/example_app/factories/team.py +35 -0
- wbcore/contrib/example_app/filters/__init__.py +9 -0
- wbcore/contrib/example_app/filters/event.py +80 -0
- wbcore/contrib/example_app/filters/league.py +74 -0
- wbcore/contrib/example_app/filters/match.py +92 -0
- wbcore/contrib/example_app/filters/person.py +77 -0
- wbcore/contrib/example_app/filters/role.py +17 -0
- wbcore/contrib/example_app/filters/sport.py +26 -0
- wbcore/contrib/example_app/filters/stadium.py +30 -0
- wbcore/contrib/example_app/filters/team.py +77 -0
- wbcore/contrib/example_app/filters/teamresult.py +47 -0
- wbcore/contrib/example_app/migrations/0001_initial.py +498 -0
- wbcore/contrib/example_app/migrations/0002_sportperson_profile.py +49 -0
- wbcore/contrib/example_app/migrations/0003_change_stadium_capacity.py +31 -0
- wbcore/contrib/example_app/migrations/0004_alter_player_transfer_value.py +21 -0
- wbcore/contrib/example_app/migrations/0005_sportperson_profile_image.py +23 -0
- wbcore/contrib/example_app/migrations/0006_league_season_period_player_is_active_and_more.py +116 -0
- wbcore/contrib/example_app/migrations/0007_alter_player_options_alter_team_options_and_more.py +40 -0
- wbcore/contrib/example_app/migrations/__init__.py +0 -0
- wbcore/contrib/example_app/models.py +906 -0
- wbcore/contrib/example_app/serializers/__init__.py +31 -0
- wbcore/contrib/example_app/serializers/league.py +111 -0
- wbcore/contrib/example_app/serializers/match_event.py +304 -0
- wbcore/contrib/example_app/serializers/person_team.py +280 -0
- wbcore/contrib/example_app/serializers/role.py +16 -0
- wbcore/contrib/example_app/serializers/season.py +53 -0
- wbcore/contrib/example_app/serializers/sport.py +37 -0
- wbcore/contrib/example_app/serializers/stadium.py +58 -0
- wbcore/contrib/example_app/serializers/teamresult.py +43 -0
- wbcore/contrib/example_app/tests/__init__.py +0 -0
- wbcore/contrib/example_app/tests/conftest.py +13 -0
- wbcore/contrib/example_app/tests/e2e/__init__.py +1 -0
- wbcore/contrib/example_app/tests/e2e/e2e_example_app_utility.py +51 -0
- wbcore/contrib/example_app/tests/e2e/test_league.py +69 -0
- wbcore/contrib/example_app/tests/e2e/test_person.py +67 -0
- wbcore/contrib/example_app/tests/e2e/test_teams.py +56 -0
- wbcore/contrib/example_app/tests/signals.py +7 -0
- wbcore/contrib/example_app/tests/test_displays.py +40 -0
- wbcore/contrib/example_app/tests/test_filters.py +70 -0
- wbcore/contrib/example_app/tests/test_utils.py +25 -0
- wbcore/contrib/example_app/urls.py +79 -0
- wbcore/contrib/example_app/utils.py +20 -0
- wbcore/contrib/example_app/viewsets/__init__.py +29 -0
- wbcore/contrib/example_app/viewsets/buttons/__init__.py +2 -0
- wbcore/contrib/example_app/viewsets/buttons/person.py +18 -0
- wbcore/contrib/example_app/viewsets/buttons/team.py +23 -0
- wbcore/contrib/example_app/viewsets/displays/__init__.py +23 -0
- wbcore/contrib/example_app/viewsets/displays/event.py +186 -0
- wbcore/contrib/example_app/viewsets/displays/league.py +390 -0
- wbcore/contrib/example_app/viewsets/displays/match.py +264 -0
- wbcore/contrib/example_app/viewsets/displays/person.py +251 -0
- wbcore/contrib/example_app/viewsets/displays/role.py +16 -0
- wbcore/contrib/example_app/viewsets/displays/season.py +65 -0
- wbcore/contrib/example_app/viewsets/displays/sport.py +115 -0
- wbcore/contrib/example_app/viewsets/displays/stadium.py +149 -0
- wbcore/contrib/example_app/viewsets/displays/team.py +230 -0
- wbcore/contrib/example_app/viewsets/displays/teamresult.py +30 -0
- wbcore/contrib/example_app/viewsets/endpoints/__init__.py +12 -0
- wbcore/contrib/example_app/viewsets/endpoints/endpoints.py +79 -0
- wbcore/contrib/example_app/viewsets/event.py +287 -0
- wbcore/contrib/example_app/viewsets/league.py +72 -0
- wbcore/contrib/example_app/viewsets/match.py +119 -0
- wbcore/contrib/example_app/viewsets/menu/__init__.py +1 -0
- wbcore/contrib/example_app/viewsets/menu/menus.py +102 -0
- wbcore/contrib/example_app/viewsets/menus.py +63 -0
- wbcore/contrib/example_app/viewsets/person.py +133 -0
- wbcore/contrib/example_app/viewsets/role.py +25 -0
- wbcore/contrib/example_app/viewsets/season.py +23 -0
- wbcore/contrib/example_app/viewsets/sport.py +26 -0
- wbcore/contrib/example_app/viewsets/stadium.py +30 -0
- wbcore/contrib/example_app/viewsets/team.py +68 -0
- wbcore/contrib/example_app/viewsets/teamresult.py +106 -0
- wbcore/contrib/example_app/viewsets/titles/__init__.py +9 -0
- wbcore/contrib/example_app/viewsets/titles/event.py +41 -0
- wbcore/contrib/example_app/viewsets/titles/league.py +24 -0
- wbcore/contrib/example_app/viewsets/titles/match.py +34 -0
- wbcore/contrib/example_app/viewsets/titles/person.py +35 -0
- wbcore/contrib/example_app/viewsets/titles/role.py +13 -0
- wbcore/contrib/example_app/viewsets/titles/sport.py +13 -0
- wbcore/contrib/example_app/viewsets/titles/stadium.py +13 -0
- wbcore/contrib/example_app/viewsets/titles/team.py +24 -0
- wbcore/contrib/example_app/viewsets/titles/teamresult.py +12 -0
- wbcore/contrib/geography/__init__.py +0 -0
- wbcore/contrib/geography/admin.py +30 -0
- wbcore/contrib/geography/apps.py +5 -0
- wbcore/contrib/geography/factories.py +46 -0
- wbcore/contrib/geography/import_export/__init__.py +0 -0
- wbcore/contrib/geography/import_export/resources/__init__.py +0 -0
- wbcore/contrib/geography/import_export/resources/geography.py +10 -0
- wbcore/contrib/geography/migrations/0001_initial.py +110 -0
- wbcore/contrib/geography/migrations/__init__.py +0 -0
- wbcore/contrib/geography/models.py +147 -0
- wbcore/contrib/geography/release_notes/1_0_0.md +13 -0
- wbcore/contrib/geography/release_notes/__init__.py +0 -0
- wbcore/contrib/geography/serializers.py +32 -0
- wbcore/contrib/geography/tests/__init__.py +0 -0
- wbcore/contrib/geography/tests/conftest.py +12 -0
- wbcore/contrib/geography/tests/signals.py +7 -0
- wbcore/contrib/geography/tests/test_models.py +12 -0
- wbcore/contrib/geography/tests/test_serializers.py +7 -0
- wbcore/contrib/geography/tests/test_viewsets.py +6 -0
- wbcore/contrib/geography/tests/tests.py +12 -0
- wbcore/contrib/geography/urls.py +12 -0
- wbcore/contrib/geography/viewsets/__init__.py +1 -0
- wbcore/contrib/geography/viewsets/buttons/__init__.py +0 -0
- wbcore/contrib/geography/viewsets/display/__init__.py +1 -0
- wbcore/contrib/geography/viewsets/display/geography.py +32 -0
- wbcore/contrib/geography/viewsets/endpoints/__init__.py +0 -0
- wbcore/contrib/geography/viewsets/geography.py +57 -0
- wbcore/contrib/geography/viewsets/menu/__init__.py +1 -0
- wbcore/contrib/geography/viewsets/menu/geography.py +8 -0
- wbcore/contrib/geography/viewsets/preview/__init__.py +1 -0
- wbcore/contrib/geography/viewsets/preview/geography.py +19 -0
- wbcore/contrib/geography/viewsets/titles/__init__.py +0 -0
- wbcore/contrib/geography/viewsets/titles/geography.py +14 -0
- wbcore/contrib/gleap/__init__.py +0 -0
- wbcore/contrib/gleap/apps.py +5 -0
- wbcore/contrib/gleap/configs.py +11 -0
- wbcore/contrib/gleap/configurations.py +6 -0
- wbcore/contrib/gleap/hashes.py +13 -0
- wbcore/contrib/gleap/tests/__init__.py +0 -0
- wbcore/contrib/gleap/tests/conftest.py +1 -0
- wbcore/contrib/gleap/tests/tests.py +29 -0
- wbcore/contrib/gleap/urls.py +7 -0
- wbcore/contrib/gleap/views.py +31 -0
- wbcore/contrib/guardian/migrations/0001_initial.py +103 -0
- wbcore/contrib/guardian/migrations/__init__.py +0 -0
- wbcore/contrib/guardian/models/__init__.py +1 -0
- wbcore/contrib/guardian/models/mixins.py +138 -0
- wbcore/contrib/guardian/models/models.py +29 -0
- wbcore/contrib/guardian/tests/__init__.py +0 -0
- wbcore/contrib/guardian/tests/conftest.py +1 -0
- wbcore/contrib/guardian/tests/test_model_mixins.py +93 -0
- wbcore/contrib/guardian/tests/test_tasks.py +77 -0
- wbcore/contrib/guardian/tests/test_utils.py +196 -0
- wbcore/contrib/guardian/tests/test_viewsets.py +48 -0
- wbcore/contrib/guardian/viewsets/__init__.py +1 -0
- wbcore/contrib/guardian/viewsets/configs/__init__.py +4 -0
- wbcore/contrib/guardian/viewsets/configs/buttons.py +27 -0
- wbcore/contrib/guardian/viewsets/configs/displays.py +43 -0
- wbcore/contrib/guardian/viewsets/configs/endpoints.py +18 -0
- wbcore/contrib/guardian/viewsets/configs/titles.py +16 -0
- wbcore/contrib/guardian/viewsets/mixins.py +6 -0
- wbcore/contrib/guardian/viewsets/viewsets.py +139 -0
- wbcore/contrib/icons/__init__.py +1 -0
- wbcore/contrib/icons/apps.py +5 -0
- wbcore/contrib/icons/backends/__init__.py +5 -0
- wbcore/contrib/icons/backends/default.py +374 -0
- wbcore/contrib/icons/backends/material.py +135 -0
- wbcore/contrib/icons/icons.py +169 -0
- wbcore/contrib/icons/models.py +11 -0
- wbcore/contrib/icons/serializers.py +18 -0
- wbcore/contrib/io/__init__.py +0 -0
- wbcore/contrib/io/admin.py +150 -0
- wbcore/contrib/io/apps.py +27 -0
- wbcore/contrib/io/backends/__init__.py +5 -0
- wbcore/contrib/io/backends/abstract.py +60 -0
- wbcore/contrib/io/backends/mail.py +85 -0
- wbcore/contrib/io/backends/sftp.py +63 -0
- wbcore/contrib/io/backends/stream.py +92 -0
- wbcore/contrib/io/backends/utils.py +42 -0
- wbcore/contrib/io/configs/__init__.py +0 -0
- wbcore/contrib/io/configs/endpoints.py +12 -0
- wbcore/contrib/io/configurations/__init__.py +1 -0
- wbcore/contrib/io/configurations/base.py +7 -0
- wbcore/contrib/io/dynamic_preferences_registry.py +15 -0
- wbcore/contrib/io/enums.py +15 -0
- wbcore/contrib/io/exceptions.py +16 -0
- wbcore/contrib/io/factories.py +202 -0
- wbcore/contrib/io/imports.py +305 -0
- wbcore/contrib/io/management/__init__.py +13 -0
- wbcore/contrib/io/migrations/0001_initial_squashed.py +319 -0
- wbcore/contrib/io/migrations/0002_importsource_creator.py +26 -0
- wbcore/contrib/io/migrations/0003_auto_20240103_1000.py +46 -0
- wbcore/contrib/io/migrations/0004_alter_importsource_status_exportsource.py +134 -0
- wbcore/contrib/io/migrations/0005_exportsource_data_alter_exportsource_query_str_and_more.py +67 -0
- wbcore/contrib/io/migrations/0006_alter_exportsource_query_params.py +20 -0
- wbcore/contrib/io/migrations/0007_alter_exportsource_query_params.py +23 -0
- wbcore/contrib/io/migrations/__init__.py +0 -0
- wbcore/contrib/io/mixins.py +37 -0
- wbcore/contrib/io/models.py +1005 -0
- wbcore/contrib/io/release_notes/1_0_0.md +13 -0
- wbcore/contrib/io/release_notes/__init__.py +0 -0
- wbcore/contrib/io/resources.py +177 -0
- wbcore/contrib/io/serializers.py +136 -0
- wbcore/contrib/io/tests/__init__.py +0 -0
- wbcore/contrib/io/tests/conftest.py +42 -0
- wbcore/contrib/io/tests/test_backends.py +128 -0
- wbcore/contrib/io/tests/test_exports.py +130 -0
- wbcore/contrib/io/tests/test_imports.py +167 -0
- wbcore/contrib/io/tests/test_models.py +363 -0
- wbcore/contrib/io/tests/tests.py +18 -0
- wbcore/contrib/io/urls.py +28 -0
- wbcore/contrib/io/utils.py +44 -0
- wbcore/contrib/io/viewset_mixins.py +301 -0
- wbcore/contrib/io/viewsets.py +138 -0
- wbcore/contrib/notifications/__init__.py +0 -0
- wbcore/contrib/notifications/admin.py +61 -0
- wbcore/contrib/notifications/apps.py +38 -0
- wbcore/contrib/notifications/backends/__init__.py +0 -0
- wbcore/contrib/notifications/backends/abstract_backend.py +13 -0
- wbcore/contrib/notifications/backends/console/__init__.py +1 -0
- wbcore/contrib/notifications/backends/console/backends.py +25 -0
- wbcore/contrib/notifications/backends/firebase/__init__.py +1 -0
- wbcore/contrib/notifications/backends/firebase/backends.py +102 -0
- wbcore/contrib/notifications/configs.py +12 -0
- wbcore/contrib/notifications/configurations.py +9 -0
- wbcore/contrib/notifications/dispatch.py +71 -0
- wbcore/contrib/notifications/factories/__init__.py +0 -0
- wbcore/contrib/notifications/factories/notification_types.py +22 -0
- wbcore/contrib/notifications/factories/notifications.py +16 -0
- wbcore/contrib/notifications/factories/tokens.py +11 -0
- wbcore/contrib/notifications/migrations/0001_initial.py +116 -0
- wbcore/contrib/notifications/migrations/0002_notificationusertoken_unique_user_token_device.py +18 -0
- wbcore/contrib/notifications/migrations/0003_notificationusertoken_updated.py +17 -0
- wbcore/contrib/notifications/migrations/0004_alter_notification_body.py +17 -0
- wbcore/contrib/notifications/migrations/0005_alter_notification_endpoint.py +17 -0
- wbcore/contrib/notifications/migrations/0006_notification_created.py +25 -0
- wbcore/contrib/notifications/migrations/__init__.py +0 -0
- wbcore/contrib/notifications/models/__init__.py +3 -0
- wbcore/contrib/notifications/models/notification_types.py +112 -0
- wbcore/contrib/notifications/models/notifications.py +81 -0
- wbcore/contrib/notifications/models/tokens.py +45 -0
- wbcore/contrib/notifications/release_notes/1_0_0.md +13 -0
- wbcore/contrib/notifications/release_notes/__init__.py +0 -0
- wbcore/contrib/notifications/serializers/__init__.py +5 -0
- wbcore/contrib/notifications/serializers/notification_types.py +36 -0
- wbcore/contrib/notifications/serializers/notifications.py +33 -0
- wbcore/contrib/notifications/tasks.py +55 -0
- wbcore/contrib/notifications/tests/__init__.py +0 -0
- wbcore/contrib/notifications/tests/conftest.py +47 -0
- wbcore/contrib/notifications/tests/test_backends/__init__.py +0 -0
- wbcore/contrib/notifications/tests/test_backends/test_firebase.py +78 -0
- wbcore/contrib/notifications/tests/test_configs.py +7 -0
- wbcore/contrib/notifications/tests/test_models/__init__.py +0 -0
- wbcore/contrib/notifications/tests/test_models/test_notification_types.py +84 -0
- wbcore/contrib/notifications/tests/test_models/test_notifications.py +45 -0
- wbcore/contrib/notifications/tests/test_models/test_tokens.py +21 -0
- wbcore/contrib/notifications/tests/test_serializers/__init__.py +0 -0
- wbcore/contrib/notifications/tests/test_serializers/test_notification_types.py +53 -0
- wbcore/contrib/notifications/tests/test_serializers/test_notifications.py +23 -0
- wbcore/contrib/notifications/tests/test_tasks.py +71 -0
- wbcore/contrib/notifications/tests/test_utils.py +0 -0
- wbcore/contrib/notifications/tests/test_viewsets/__init__.py +0 -0
- wbcore/contrib/notifications/tests/test_viewsets/test_notification_types.py +121 -0
- wbcore/contrib/notifications/tests/test_viewsets/test_notifications.py +120 -0
- wbcore/contrib/notifications/urls.py +26 -0
- wbcore/contrib/notifications/utils.py +20 -0
- wbcore/contrib/notifications/views.py +62 -0
- wbcore/contrib/notifications/viewsets/__init__.py +5 -0
- wbcore/contrib/notifications/viewsets/menus.py +14 -0
- wbcore/contrib/notifications/viewsets/notification_types.py +40 -0
- wbcore/contrib/notifications/viewsets/notifications.py +57 -0
- wbcore/contrib/tags/__init__.py +0 -0
- wbcore/contrib/tags/admin.py +17 -0
- wbcore/contrib/tags/apps.py +9 -0
- wbcore/contrib/tags/factories.py +27 -0
- wbcore/contrib/tags/filters.py +42 -0
- wbcore/contrib/tags/migrations/0001_initial.py +62 -0
- wbcore/contrib/tags/migrations/__init__.py +0 -0
- wbcore/contrib/tags/models/__init__.py +2 -0
- wbcore/contrib/tags/models/mixins.py +27 -0
- wbcore/contrib/tags/models/tags.py +103 -0
- wbcore/contrib/tags/release_notes/1_0_0.md +13 -0
- wbcore/contrib/tags/release_notes/__init__.py +0 -0
- wbcore/contrib/tags/serializers.py +87 -0
- wbcore/contrib/tags/signals.py +17 -0
- wbcore/contrib/tags/tests/__init__.py +0 -0
- wbcore/contrib/tags/tests/conftest.py +7 -0
- wbcore/contrib/tags/tests/tests.py +17 -0
- wbcore/contrib/tags/urls.py +14 -0
- wbcore/contrib/tags/viewsets/__init__.py +8 -0
- wbcore/contrib/tags/viewsets/display.py +50 -0
- wbcore/contrib/tags/viewsets/menu.py +15 -0
- wbcore/contrib/tags/viewsets/viewsets.py +58 -0
- wbcore/contrib/workflow/__init__.py +1 -0
- wbcore/contrib/workflow/admin/__init__.py +15 -0
- wbcore/contrib/workflow/admin/condition.py +8 -0
- wbcore/contrib/workflow/admin/data.py +14 -0
- wbcore/contrib/workflow/admin/display.py +8 -0
- wbcore/contrib/workflow/admin/process.py +36 -0
- wbcore/contrib/workflow/admin/step.py +91 -0
- wbcore/contrib/workflow/admin/transition.py +8 -0
- wbcore/contrib/workflow/admin/workflow.py +8 -0
- wbcore/contrib/workflow/apps.py +26 -0
- wbcore/contrib/workflow/configs.py +10 -0
- wbcore/contrib/workflow/decorators.py +25 -0
- wbcore/contrib/workflow/dispatch.py +23 -0
- wbcore/contrib/workflow/factories/__init__.py +18 -0
- wbcore/contrib/workflow/factories/condition.py +15 -0
- wbcore/contrib/workflow/factories/data.py +22 -0
- wbcore/contrib/workflow/factories/display.py +27 -0
- wbcore/contrib/workflow/factories/process.py +69 -0
- wbcore/contrib/workflow/factories/step.py +155 -0
- wbcore/contrib/workflow/factories/transition.py +25 -0
- wbcore/contrib/workflow/factories/workflow.py +19 -0
- wbcore/contrib/workflow/filters/__init__.py +24 -0
- wbcore/contrib/workflow/filters/condition.py +23 -0
- wbcore/contrib/workflow/filters/data.py +24 -0
- wbcore/contrib/workflow/filters/process.py +164 -0
- wbcore/contrib/workflow/filters/step.py +226 -0
- wbcore/contrib/workflow/filters/transition.py +41 -0
- wbcore/contrib/workflow/filters/workflow.py +43 -0
- wbcore/contrib/workflow/migrations/0001_initial.py +788 -0
- wbcore/contrib/workflow/migrations/0002_alter_step_step_type.py +31 -0
- wbcore/contrib/workflow/migrations/0003_alter_condition_attribute_name_and_more.py +75 -0
- wbcore/contrib/workflow/migrations/0004_alter_userstep_assignee_method.py +27 -0
- wbcore/contrib/workflow/migrations/0005_alter_userstep_assignee_method.py +17 -0
- wbcore/contrib/workflow/migrations/__init__.py +0 -0
- wbcore/contrib/workflow/models/__init__.py +19 -0
- wbcore/contrib/workflow/models/condition.py +123 -0
- wbcore/contrib/workflow/models/data.py +238 -0
- wbcore/contrib/workflow/models/display.py +33 -0
- wbcore/contrib/workflow/models/process.py +243 -0
- wbcore/contrib/workflow/models/step.py +735 -0
- wbcore/contrib/workflow/models/transition.py +70 -0
- wbcore/contrib/workflow/models/workflow.py +307 -0
- wbcore/contrib/workflow/serializers/__init__.py +37 -0
- wbcore/contrib/workflow/serializers/condition.py +64 -0
- wbcore/contrib/workflow/serializers/data.py +135 -0
- wbcore/contrib/workflow/serializers/display.py +25 -0
- wbcore/contrib/workflow/serializers/process.py +182 -0
- wbcore/contrib/workflow/serializers/signals.py +25 -0
- wbcore/contrib/workflow/serializers/step.py +364 -0
- wbcore/contrib/workflow/serializers/transition.py +80 -0
- wbcore/contrib/workflow/serializers/workflow.py +124 -0
- wbcore/contrib/workflow/sites.py +43 -0
- wbcore/contrib/workflow/tests/__init__.py +0 -0
- wbcore/contrib/workflow/tests/conftest.py +57 -0
- wbcore/contrib/workflow/tests/test_configs.py +6 -0
- wbcore/contrib/workflow/tests/test_dispatch.py +88 -0
- wbcore/contrib/workflow/tests/test_displays.py +119 -0
- wbcore/contrib/workflow/tests/test_filters.py +86 -0
- wbcore/contrib/workflow/tests/test_serializers.py +177 -0
- wbcore/contrib/workflow/tests/test_viewsets.py +358 -0
- wbcore/contrib/workflow/tests/test_workflow_assignees.py +225 -0
- wbcore/contrib/workflow/tests/tests.py +24 -0
- wbcore/contrib/workflow/urls.py +66 -0
- wbcore/contrib/workflow/utils.py +13 -0
- wbcore/contrib/workflow/viewsets/__init__.py +17 -0
- wbcore/contrib/workflow/viewsets/buttons/__init__.py +1 -0
- wbcore/contrib/workflow/viewsets/buttons/step.py +67 -0
- wbcore/contrib/workflow/viewsets/condition.py +32 -0
- wbcore/contrib/workflow/viewsets/data.py +33 -0
- wbcore/contrib/workflow/viewsets/display/__init__.py +15 -0
- wbcore/contrib/workflow/viewsets/display/condition.py +50 -0
- wbcore/contrib/workflow/viewsets/display/data.py +50 -0
- wbcore/contrib/workflow/viewsets/display/process.py +185 -0
- wbcore/contrib/workflow/viewsets/display/step.py +453 -0
- wbcore/contrib/workflow/viewsets/display/transition.py +75 -0
- wbcore/contrib/workflow/viewsets/display/workflow.py +167 -0
- wbcore/contrib/workflow/viewsets/endpoints/__init__.py +5 -0
- wbcore/contrib/workflow/viewsets/endpoints/condition.py +9 -0
- wbcore/contrib/workflow/viewsets/endpoints/data.py +9 -0
- wbcore/contrib/workflow/viewsets/endpoints/process.py +11 -0
- wbcore/contrib/workflow/viewsets/endpoints/step.py +24 -0
- wbcore/contrib/workflow/viewsets/endpoints/transition.py +18 -0
- wbcore/contrib/workflow/viewsets/menu/__init__.py +15 -0
- wbcore/contrib/workflow/viewsets/menu/condition.py +18 -0
- wbcore/contrib/workflow/viewsets/menu/data.py +18 -0
- wbcore/contrib/workflow/viewsets/menu/process.py +18 -0
- wbcore/contrib/workflow/viewsets/menu/step.py +123 -0
- wbcore/contrib/workflow/viewsets/menu/transition.py +18 -0
- wbcore/contrib/workflow/viewsets/menu/workflow.py +18 -0
- wbcore/contrib/workflow/viewsets/process.py +171 -0
- wbcore/contrib/workflow/viewsets/step.py +229 -0
- wbcore/contrib/workflow/viewsets/titles/__init__.py +16 -0
- wbcore/contrib/workflow/viewsets/titles/condition.py +13 -0
- wbcore/contrib/workflow/viewsets/titles/data.py +13 -0
- wbcore/contrib/workflow/viewsets/titles/process.py +26 -0
- wbcore/contrib/workflow/viewsets/titles/step.py +101 -0
- wbcore/contrib/workflow/viewsets/titles/transition.py +13 -0
- wbcore/contrib/workflow/viewsets/titles/workflow.py +13 -0
- wbcore/contrib/workflow/viewsets/transition.py +57 -0
- wbcore/contrib/workflow/viewsets/workflow.py +36 -0
- wbcore/contrib/workflow/workflows/__init__.py +1 -0
- wbcore/contrib/workflow/workflows/assignees.py +82 -0
- wbcore/crontab/__init__.py +0 -0
- wbcore/crontab/serializers.py +23 -0
- wbcore/crontab/viewsets.py +9 -0
- wbcore/dispatch.py +55 -0
- wbcore/docs/__init__.py +25 -0
- wbcore/docs/orderable.md +29 -0
- wbcore/docs/reparent.md +13 -0
- wbcore/dynamic_preferences_registry.py +29 -0
- wbcore/enums.py +98 -0
- wbcore/filters/__init__.py +21 -0
- wbcore/filters/backends.py +19 -0
- wbcore/filters/defaults.py +69 -0
- wbcore/filters/fields/__init__.py +15 -0
- wbcore/filters/fields/booleans.py +6 -0
- wbcore/filters/fields/choices.py +61 -0
- wbcore/filters/fields/content_type.py +33 -0
- wbcore/filters/fields/datetime.py +91 -0
- wbcore/filters/fields/models.py +113 -0
- wbcore/filters/fields/multiple_lookups.py +19 -0
- wbcore/filters/fields/numbers.py +46 -0
- wbcore/filters/fields/text.py +6 -0
- wbcore/filters/filterset.py +217 -0
- wbcore/filters/lookups.py +41 -0
- wbcore/filters/mixins.py +112 -0
- wbcore/filters/utils.py +21 -0
- wbcore/forms.py +125 -0
- wbcore/frontend.py +23 -0
- wbcore/frontend_user_configuration.py +96 -0
- wbcore/fsm/__init__.py +0 -0
- wbcore/fsm/markdown_extensions.py +31 -0
- wbcore/fsm/mixins.py +114 -0
- wbcore/management/__init__.py +88 -0
- wbcore/management/commands/__init__.py +0 -0
- wbcore/management/commands/bootstrap.py +18 -0
- wbcore/management/commands/clean_obsolete_object.py +21 -0
- wbcore/management/commands/handle_release_notes.py +53 -0
- wbcore/markdown/__init__.py +1 -0
- wbcore/markdown/admin.py +9 -0
- wbcore/markdown/dynamic_preferences_registry.py +16 -0
- wbcore/markdown/models.py +38 -0
- wbcore/markdown/template.py +38 -0
- wbcore/markdown/utils.py +36 -0
- wbcore/markdown/views.py +67 -0
- wbcore/menus/__init__.py +2 -0
- wbcore/menus/menus.py +96 -0
- wbcore/menus/registry.py +28 -0
- wbcore/menus/views.py +41 -0
- wbcore/messages.py +51 -0
- wbcore/metadata/__init__.py +0 -0
- wbcore/metadata/configs/__init__.py +0 -0
- wbcore/metadata/configs/base.py +86 -0
- wbcore/metadata/configs/buttons/__init__.py +4 -0
- wbcore/metadata/configs/buttons/bases.py +91 -0
- wbcore/metadata/configs/buttons/buttons.py +142 -0
- wbcore/metadata/configs/buttons/enums.py +25 -0
- wbcore/metadata/configs/buttons/metadata.py +8 -0
- wbcore/metadata/configs/buttons/view_config.py +176 -0
- wbcore/metadata/configs/display/__init__.py +4 -0
- wbcore/metadata/configs/display/configs.py +15 -0
- wbcore/metadata/configs/display/display.py +234 -0
- wbcore/metadata/configs/display/formatting.py +50 -0
- wbcore/metadata/configs/display/instance_display/__init__.py +15 -0
- wbcore/metadata/configs/display/instance_display/display.py +37 -0
- wbcore/metadata/configs/display/instance_display/enums.py +7 -0
- wbcore/metadata/configs/display/instance_display/layouts/__init__.py +3 -0
- wbcore/metadata/configs/display/instance_display/layouts/inlines.py +58 -0
- wbcore/metadata/configs/display/instance_display/layouts/layouts.py +77 -0
- wbcore/metadata/configs/display/instance_display/layouts/sections.py +43 -0
- wbcore/metadata/configs/display/instance_display/operators.py +22 -0
- wbcore/metadata/configs/display/instance_display/pages.py +40 -0
- wbcore/metadata/configs/display/instance_display/shortcuts.py +70 -0
- wbcore/metadata/configs/display/instance_display/signals.py +3 -0
- wbcore/metadata/configs/display/instance_display/styles.py +42 -0
- wbcore/metadata/configs/display/instance_display/utils.py +74 -0
- wbcore/metadata/configs/display/list_display.py +230 -0
- wbcore/metadata/configs/display/models.py +20 -0
- wbcore/metadata/configs/display/view_config.py +82 -0
- wbcore/metadata/configs/display/views.py +48 -0
- wbcore/metadata/configs/display/windows.py +28 -0
- wbcore/metadata/configs/documentations.py +11 -0
- wbcore/metadata/configs/endpoints.py +176 -0
- wbcore/metadata/configs/fields.py +17 -0
- wbcore/metadata/configs/filter_fields.py +42 -0
- wbcore/metadata/configs/identifiers.py +25 -0
- wbcore/metadata/configs/ordering_fields.py +24 -0
- wbcore/metadata/configs/paginations.py +11 -0
- wbcore/metadata/configs/preview.py +41 -0
- wbcore/metadata/configs/primary_keys.py +9 -0
- wbcore/metadata/configs/search_fields.py +9 -0
- wbcore/metadata/configs/titles.py +48 -0
- wbcore/metadata/configs/window_types.py +13 -0
- wbcore/metadata/exceptions.py +0 -0
- wbcore/metadata/metadata.py +33 -0
- wbcore/metadata/mixins.py +105 -0
- wbcore/metadata/tests/__init__.py +0 -0
- wbcore/metadata/tests/test_buttons.py +179 -0
- wbcore/metadata/utils.py +4 -0
- wbcore/migrations/0001_initial_squashed_squashed_0010_preset_appliedpreset.py +398 -0
- wbcore/migrations/0011_genericmodel.py +22 -0
- wbcore/migrations/0012_delete_notification.py +15 -0
- wbcore/migrations/0013_delete_colorgradient.py +14 -0
- wbcore/migrations/0014_biguserobjectpermission_system.py +44 -0
- wbcore/migrations/__init__.py +0 -0
- wbcore/models/__init__.py +6 -0
- wbcore/models/base.py +182 -0
- wbcore/models/fields.py +29 -0
- wbcore/models/orderable.py +6 -0
- wbcore/pagination.py +65 -0
- wbcore/pandas/__init__.py +0 -0
- wbcore/pandas/fields.py +136 -0
- wbcore/pandas/filters.py +113 -0
- wbcore/pandas/filterset.py +26 -0
- wbcore/pandas/metadata.py +14 -0
- wbcore/pandas/utils.py +129 -0
- wbcore/pandas/views.py +157 -0
- wbcore/permissions/__init__.py +0 -0
- wbcore/permissions/backend.py +35 -0
- wbcore/permissions/mixins.py +72 -0
- wbcore/permissions/permissions.py +50 -0
- wbcore/permissions/registry.py +32 -0
- wbcore/permissions/shortcuts.py +37 -0
- wbcore/permissions/utils.py +26 -0
- wbcore/release_notes/__init__.py +0 -0
- wbcore/release_notes/admin.py +30 -0
- wbcore/release_notes/buttons.py +25 -0
- wbcore/release_notes/display.py +57 -0
- wbcore/release_notes/filters.py +35 -0
- wbcore/release_notes/models.py +65 -0
- wbcore/release_notes/serializers.py +19 -0
- wbcore/release_notes/utils.py +14 -0
- wbcore/release_notes/viewsets.py +45 -0
- wbcore/reversion/__init__.py +0 -0
- wbcore/reversion/filters.py +38 -0
- wbcore/reversion/serializers.py +80 -0
- wbcore/reversion/viewsets/__init__.py +6 -0
- wbcore/reversion/viewsets/buttons.py +94 -0
- wbcore/reversion/viewsets/displays.py +44 -0
- wbcore/reversion/viewsets/endpoints.py +29 -0
- wbcore/reversion/viewsets/titles.py +17 -0
- wbcore/reversion/viewsets/viewsets.py +111 -0
- wbcore/routers.py +63 -0
- wbcore/search/__init__.py +62 -0
- wbcore/serializers/__init__.py +66 -0
- wbcore/serializers/fields/__init__.py +58 -0
- wbcore/serializers/fields/boolean.py +51 -0
- wbcore/serializers/fields/choice.py +36 -0
- wbcore/serializers/fields/datetime.py +143 -0
- wbcore/serializers/fields/fields.py +190 -0
- wbcore/serializers/fields/file.py +20 -0
- wbcore/serializers/fields/fsm.py +20 -0
- wbcore/serializers/fields/json.py +56 -0
- wbcore/serializers/fields/list.py +105 -0
- wbcore/serializers/fields/mixins.py +175 -0
- wbcore/serializers/fields/number.py +103 -0
- wbcore/serializers/fields/other.py +42 -0
- wbcore/serializers/fields/primary_key.py +22 -0
- wbcore/serializers/fields/related.py +152 -0
- wbcore/serializers/fields/text.py +136 -0
- wbcore/serializers/fields/types.py +41 -0
- wbcore/serializers/mixins.py +24 -0
- wbcore/serializers/serializers.py +415 -0
- wbcore/serializers/utils.py +142 -0
- wbcore/shares/__init__.py +1 -0
- wbcore/shares/config.py +63 -0
- wbcore/shares/decorator.py +13 -0
- wbcore/shares/signals.py +3 -0
- wbcore/shares/sites.py +28 -0
- wbcore/shares/views.py +24 -0
- wbcore/signals/__init__.py +6 -0
- wbcore/signals/filters.py +3 -0
- wbcore/signals/instance_buttons.py +5 -0
- wbcore/signals/merge.py +4 -0
- wbcore/signals/models.py +8 -0
- wbcore/signals/permissions.py +3 -0
- wbcore/signals/serializers.py +5 -0
- wbcore/tasks.py +83 -0
- wbcore/templates/reversion/__init__.py +0 -0
- wbcore/templates/reversion/compare_detail.html +19 -0
- wbcore/test/__init__.py +30 -0
- wbcore/test/mixins.py +709 -0
- wbcore/test/signals.py +6 -0
- wbcore/test/tests.py +131 -0
- wbcore/test/utils.py +227 -0
- wbcore/tests/__init__.py +0 -0
- wbcore/tests/conftest.py +55 -0
- wbcore/tests/e2e/__init__.py +0 -0
- wbcore/tests/e2e/test_e2e.py +24 -0
- wbcore/tests/models.py +6 -0
- wbcore/tests/test_cache/__init__.py +0 -0
- wbcore/tests/test_cache/test_decorators.py +30 -0
- wbcore/tests/test_cache/test_mixins.py +29 -0
- wbcore/tests/test_cache/test_registry.py +57 -0
- wbcore/tests/test_configs.py +65 -0
- wbcore/tests/test_enums.py +54 -0
- wbcore/tests/test_fields/__init__.py +0 -0
- wbcore/tests/test_fields/test_boolean_fields.py +48 -0
- wbcore/tests/test_fields/test_choice_fields.py +48 -0
- wbcore/tests/test_fields/test_datetime_fields.py +151 -0
- wbcore/tests/test_fields/test_fields.py +23 -0
- wbcore/tests/test_fields/test_file_fields.py +52 -0
- wbcore/tests/test_fields/test_json_fields.py +28 -0
- wbcore/tests/test_fields/test_list_fields.py +27 -0
- wbcore/tests/test_fields/test_mixins.py +111 -0
- wbcore/tests/test_fields/test_number_fields.py +190 -0
- wbcore/tests/test_fields/test_other_fields.py +61 -0
- wbcore/tests/test_fields/test_primary_key_fields.py +52 -0
- wbcore/tests/test_fields/test_related.py +80 -0
- wbcore/tests/test_fields/test_text_fields.py +117 -0
- wbcore/tests/test_filters/__init__.py +0 -0
- wbcore/tests/test_filters/test_mixins.py +108 -0
- wbcore/tests/test_filters/test_pandas.py +114 -0
- wbcore/tests/test_list_display.py +31 -0
- wbcore/tests/test_models/__init__.py +0 -0
- wbcore/tests/test_models/test_fields.py +25 -0
- wbcore/tests/test_models/test_mixins.py +31 -0
- wbcore/tests/test_new_display/__init__.py +0 -0
- wbcore/tests/test_new_display/test_inlines.py +13 -0
- wbcore/tests/test_new_display/test_layouts.py +15 -0
- wbcore/tests/test_new_display/test_operators.py +15 -0
- wbcore/tests/test_new_display/test_pages.py +8 -0
- wbcore/tests/test_new_display/test_sections.py +0 -0
- wbcore/tests/test_new_display/test_shortcuts.py +38 -0
- wbcore/tests/test_new_display/test_utils.py +48 -0
- wbcore/tests/test_pagination.py +31 -0
- wbcore/tests/test_serializers/__init__.py +0 -0
- wbcore/tests/test_serializers/test_fields.py +140 -0
- wbcore/tests/test_serializers/test_mixins.py +53 -0
- wbcore/tests/test_serializers/test_related.py +77 -0
- wbcore/tests/test_something.py +39 -0
- wbcore/tests/test_utils/__init__.py +0 -0
- wbcore/tests/test_utils/test_date.py +49 -0
- wbcore/tests/test_utils/test_date_builder.py +99 -0
- wbcore/tests/test_utils/test_primary.py +79 -0
- wbcore/tests/test_utils/test_signals.py +38 -0
- wbcore/tests/test_viewsets.py +20 -0
- wbcore/urls.py +114 -0
- wbcore/utils/__init__.py +13 -0
- wbcore/utils/cache.py +8 -0
- wbcore/utils/date.py +220 -0
- wbcore/utils/date_builder/__init__.py +18 -0
- wbcore/utils/date_builder/components.py +42 -0
- wbcore/utils/date_builder/offsets.py +27 -0
- wbcore/utils/deprecations.py +11 -0
- wbcore/utils/enum.py +23 -0
- wbcore/utils/figures.py +290 -0
- wbcore/utils/html.py +8 -0
- wbcore/utils/importlib.py +13 -0
- wbcore/utils/itertools.py +40 -0
- wbcore/utils/models.py +275 -0
- wbcore/utils/numbers.py +69 -0
- wbcore/utils/prettytable.py +35 -0
- wbcore/utils/print.py +29 -0
- wbcore/utils/renderers.py +13 -0
- wbcore/utils/rrules.py +37 -0
- wbcore/utils/serializers.py +8 -0
- wbcore/utils/settings.py +5 -0
- wbcore/utils/signals.py +36 -0
- wbcore/utils/string_loader.py +42 -0
- wbcore/utils/strings.py +77 -0
- wbcore/utils/task.py +6 -0
- wbcore/utils/urls.py +70 -0
- wbcore/utils/views.py +201 -0
- wbcore/views.py +26 -0
- wbcore/viewsets/__init__.py +10 -0
- wbcore/viewsets/encoders.py +18 -0
- wbcore/viewsets/generics.py +5 -0
- wbcore/viewsets/mixins.py +290 -0
- wbcore/viewsets/utils.py +26 -0
- wbcore/viewsets/viewsets.py +142 -0
- wbcore-2.2.1.dist-info/METADATA +62 -0
- wbcore-2.2.1.dist-info/RECORD +1035 -0
- wbcore-2.2.1.dist-info/WHEEL +5 -0
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
from datetime import date, timedelta
|
|
2
|
+
from decimal import Decimal
|
|
3
|
+
|
|
4
|
+
import pytest
|
|
5
|
+
from django.contrib.postgres.aggregates import ArrayAgg
|
|
6
|
+
from django.db.models import Q
|
|
7
|
+
from django.forms.models import model_to_dict
|
|
8
|
+
from rest_framework import status
|
|
9
|
+
from rest_framework.test import APIRequestFactory
|
|
10
|
+
from wbcore.contrib.authentication.factories import SuperUserFactory
|
|
11
|
+
from wbcore.contrib.currency.factories import CurrencyFactory, CurrencyFXRatesFactory
|
|
12
|
+
from wbcore.contrib.currency.models import Currency
|
|
13
|
+
from wbcore.contrib.currency.viewsets import (
|
|
14
|
+
CurrencyModelViewSet,
|
|
15
|
+
CurrencyRepresentationViewSet,
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@pytest.mark.viewset_tests
|
|
20
|
+
@pytest.mark.currency_representation_viewset_tests
|
|
21
|
+
@pytest.mark.with_db
|
|
22
|
+
@pytest.mark.django_db
|
|
23
|
+
class TestCurrencyRepresentationViewSets:
|
|
24
|
+
@pytest.fixture()
|
|
25
|
+
def test_request(self):
|
|
26
|
+
factory = APIRequestFactory()
|
|
27
|
+
request = factory.get("")
|
|
28
|
+
request.user = SuperUserFactory()
|
|
29
|
+
return request
|
|
30
|
+
|
|
31
|
+
def test_currency_list_representation_viewset(self, test_request, currency_factory):
|
|
32
|
+
# Arrange
|
|
33
|
+
currency_factory.create_batch(2)
|
|
34
|
+
vs = CurrencyRepresentationViewSet.as_view({"get": "list"})
|
|
35
|
+
# Act
|
|
36
|
+
response = vs(test_request)
|
|
37
|
+
# Assert
|
|
38
|
+
assert response.status_code == status.HTTP_200_OK
|
|
39
|
+
assert response.data
|
|
40
|
+
assert len(response.data["results"]) == 2
|
|
41
|
+
|
|
42
|
+
def test_currency_representation_viewset(self, test_request, currency_factory):
|
|
43
|
+
# Arrange
|
|
44
|
+
euro = currency_factory(symbol="€", key="EUR", title="Euro")
|
|
45
|
+
vs = CurrencyRepresentationViewSet.as_view({"get": "retrieve"})
|
|
46
|
+
# Act
|
|
47
|
+
response = vs(test_request, pk=euro.pk)
|
|
48
|
+
instance = response.data.get("instance")
|
|
49
|
+
# Assert
|
|
50
|
+
assert response.status_code == status.HTTP_200_OK
|
|
51
|
+
assert instance.get("id") == euro.id
|
|
52
|
+
assert instance.get("key") == euro.key
|
|
53
|
+
assert instance.get("title") == euro.title
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
@pytest.mark.viewset_tests
|
|
57
|
+
@pytest.mark.currency_viewset_tests
|
|
58
|
+
@pytest.mark.with_db
|
|
59
|
+
@pytest.mark.django_db
|
|
60
|
+
class TestCurrencyViewSets:
|
|
61
|
+
@pytest.fixture()
|
|
62
|
+
def api_rf(self):
|
|
63
|
+
factory = APIRequestFactory()
|
|
64
|
+
return factory
|
|
65
|
+
|
|
66
|
+
@pytest.fixture()
|
|
67
|
+
def su(self):
|
|
68
|
+
super_user = SuperUserFactory()
|
|
69
|
+
return super_user
|
|
70
|
+
|
|
71
|
+
@pytest.fixture()
|
|
72
|
+
def get_request(self, api_rf, su):
|
|
73
|
+
request = api_rf.get("")
|
|
74
|
+
request.user = su
|
|
75
|
+
return request
|
|
76
|
+
|
|
77
|
+
@pytest.fixture()
|
|
78
|
+
def currency(self):
|
|
79
|
+
currency = CurrencyFactory()
|
|
80
|
+
return currency
|
|
81
|
+
|
|
82
|
+
@pytest.fixture()
|
|
83
|
+
def currencies(self):
|
|
84
|
+
currency_a = CurrencyFactory()
|
|
85
|
+
currency_b = CurrencyFactory()
|
|
86
|
+
currency_c = CurrencyFactory()
|
|
87
|
+
return [currency_a, currency_b, currency_c]
|
|
88
|
+
|
|
89
|
+
def test_get_instance_request(self, get_request, currency):
|
|
90
|
+
# Arrange
|
|
91
|
+
vs = CurrencyModelViewSet.as_view({"get": "retrieve"})
|
|
92
|
+
# Act
|
|
93
|
+
response = vs(get_request, pk=currency.pk)
|
|
94
|
+
# Assert
|
|
95
|
+
assert response.status_code == status.HTTP_200_OK
|
|
96
|
+
assert not response.data.get("results")
|
|
97
|
+
assert response.data["instance"]["id"] == currency.id
|
|
98
|
+
|
|
99
|
+
def test_get_list_request(self, get_request):
|
|
100
|
+
# Arrange
|
|
101
|
+
CurrencyFactory.create_batch(3)
|
|
102
|
+
vs = CurrencyModelViewSet.as_view({"get": "list"})
|
|
103
|
+
# Act
|
|
104
|
+
response = vs(get_request)
|
|
105
|
+
# Assert
|
|
106
|
+
results = response.data.get("results")
|
|
107
|
+
assert response.status_code == status.HTTP_200_OK
|
|
108
|
+
assert not response.data.get("instance")
|
|
109
|
+
assert len(results) == 3
|
|
110
|
+
|
|
111
|
+
def test_delete_instance(self, api_rf, su, currency):
|
|
112
|
+
# Arrange
|
|
113
|
+
request = api_rf.delete("")
|
|
114
|
+
request.user = su
|
|
115
|
+
view = CurrencyModelViewSet.as_view({"delete": "destroy"})
|
|
116
|
+
# Act
|
|
117
|
+
response = view(request, pk=currency.id)
|
|
118
|
+
# Assert
|
|
119
|
+
assert response.status_code == status.HTTP_204_NO_CONTENT
|
|
120
|
+
assert Currency.objects.count() == 0
|
|
121
|
+
|
|
122
|
+
def test_update_instance(self, api_rf, su, currency):
|
|
123
|
+
# Arrange
|
|
124
|
+
new_currency = model_to_dict(CurrencyFactory.build())
|
|
125
|
+
# Add missing values to the dict, because we cannot update data with 'None' values
|
|
126
|
+
new_currency["id"] = currency.id
|
|
127
|
+
new_currency["import_source"] = ""
|
|
128
|
+
request = api_rf.put("", data=new_currency)
|
|
129
|
+
request.user = su
|
|
130
|
+
view = CurrencyModelViewSet.as_view({"put": "update"})
|
|
131
|
+
# Act
|
|
132
|
+
response = view(request, pk=currency.id)
|
|
133
|
+
instance = response.data.get("instance")
|
|
134
|
+
# Assert
|
|
135
|
+
assert response.status_code == status.HTTP_200_OK
|
|
136
|
+
assert instance["id"] == currency.id
|
|
137
|
+
assert instance["key"] == new_currency["key"]
|
|
138
|
+
assert instance["key"] != currency.key
|
|
139
|
+
|
|
140
|
+
@pytest.mark.parametrize("title", ["New_title"])
|
|
141
|
+
def test_patch_instance(self, api_rf, su, currency, title):
|
|
142
|
+
# Arrange
|
|
143
|
+
request = api_rf.patch("", data={"title": title})
|
|
144
|
+
request.user = su
|
|
145
|
+
# Act
|
|
146
|
+
view = CurrencyModelViewSet.as_view({"patch": "partial_update"})
|
|
147
|
+
response = view(request, pk=currency.id)
|
|
148
|
+
# Assert
|
|
149
|
+
assert response.status_code == status.HTTP_200_OK
|
|
150
|
+
assert response.data["instance"]["title"] == title
|
|
151
|
+
assert currency.title != title
|
|
152
|
+
currency.refresh_from_db() # The patch changes are only visible after a refresh
|
|
153
|
+
assert currency.title == title
|
|
154
|
+
|
|
155
|
+
def test_get_queryset_no_fx_rates(self, currencies):
|
|
156
|
+
viewset = CurrencyModelViewSet()
|
|
157
|
+
qs = viewset.get_queryset()
|
|
158
|
+
last_rate_date = date.today() - timedelta(days=30)
|
|
159
|
+
expected_queryset = Currency.objects.annotate(
|
|
160
|
+
fx_rates_date=ArrayAgg("fx_rates__date", filter=Q(fx_rates__date__gt=last_rate_date)),
|
|
161
|
+
fx_rates_value=ArrayAgg("fx_rates__value", filter=Q(fx_rates__date__gt=last_rate_date)),
|
|
162
|
+
)
|
|
163
|
+
assert list(qs) == list(expected_queryset)
|
|
164
|
+
for currency in qs:
|
|
165
|
+
assert currency.fx_rates_date is None
|
|
166
|
+
assert currency.fx_rates_value is None
|
|
167
|
+
|
|
168
|
+
def test_get_queryset_with_fx_rates(self, currencies):
|
|
169
|
+
recent_fx_rate_date, mid_fx_rate_date, past_cutoff_fx_rate_date = (
|
|
170
|
+
date.today() - timedelta(days=5),
|
|
171
|
+
date.today() - timedelta(days=20),
|
|
172
|
+
date.today() - timedelta(days=35),
|
|
173
|
+
)
|
|
174
|
+
value_a, value_b, value_c = (
|
|
175
|
+
Decimal("1.10"),
|
|
176
|
+
Decimal("0.85"),
|
|
177
|
+
Decimal("1.20"),
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
fx_rate_data = [
|
|
181
|
+
{"date": recent_fx_rate_date, "value": value_a},
|
|
182
|
+
{"date": mid_fx_rate_date, "value": value_b},
|
|
183
|
+
{"date": past_cutoff_fx_rate_date, "value": value_c},
|
|
184
|
+
]
|
|
185
|
+
|
|
186
|
+
for currency in currencies:
|
|
187
|
+
for data in fx_rate_data:
|
|
188
|
+
CurrencyFXRatesFactory(currency=currency, date=data["date"], value=data["value"])
|
|
189
|
+
|
|
190
|
+
viewset = CurrencyModelViewSet()
|
|
191
|
+
qs = viewset.get_queryset()
|
|
192
|
+
expected_rates = [value_a, value_b]
|
|
193
|
+
expected_dates = [recent_fx_rate_date, mid_fx_rate_date]
|
|
194
|
+
assert len(qs) == 3
|
|
195
|
+
for currency in qs:
|
|
196
|
+
assert currency.fx_rates_date == expected_dates
|
|
197
|
+
assert currency.fx_rates_value == expected_rates
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from django.urls import include, path
|
|
2
|
+
from wbcore.routers import WBCoreRouter
|
|
3
|
+
|
|
4
|
+
from .viewsets import (
|
|
5
|
+
CurrencyFXRatesCurrencyModelViewSet,
|
|
6
|
+
CurrencyModelViewSet,
|
|
7
|
+
CurrencyRepresentationViewSet,
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
router = WBCoreRouter()
|
|
11
|
+
router.register(r"currency", CurrencyModelViewSet, basename="currency")
|
|
12
|
+
router.register(r"currencyrepresentation", CurrencyRepresentationViewSet, basename="currencyrepresentation")
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
currency_router = WBCoreRouter()
|
|
16
|
+
currency_router.register(r"currencyfxrates", CurrencyFXRatesCurrencyModelViewSet, basename="currency-currencyfxrates")
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
urlpatterns = [path("", include(router.urls)), path("currency/<int:currency_id>/", include(currency_router.urls))]
|
|
File without changes
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
from datetime import date, timedelta
|
|
2
|
+
|
|
3
|
+
from django.contrib.postgres.aggregates import ArrayAgg
|
|
4
|
+
from django.db.models import Q
|
|
5
|
+
from rest_framework import filters
|
|
6
|
+
from wbcore import viewsets
|
|
7
|
+
from wbcore.filters import DjangoFilterBackend
|
|
8
|
+
|
|
9
|
+
from ..models import Currency, CurrencyFXRates
|
|
10
|
+
from ..serializers import CurrencyModelSerializer, CurrencyRepresentationSerializer
|
|
11
|
+
from .display import CurrencyDisplayConfig
|
|
12
|
+
from .preview import CurrencyPreviewConfig
|
|
13
|
+
from .titles import CurrencyTitleConfig
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class CurrencyRepresentationViewSet(viewsets.RepresentationViewSet):
|
|
17
|
+
queryset = Currency.objects.all()
|
|
18
|
+
serializer_class = CurrencyRepresentationSerializer
|
|
19
|
+
filter_backends = (filters.OrderingFilter, filters.SearchFilter)
|
|
20
|
+
|
|
21
|
+
ordering = ordering_fields = ["-symbol"]
|
|
22
|
+
search_fields = ("symbol", "key")
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class CurrencyModelViewSet(viewsets.ModelViewSet):
|
|
26
|
+
display_config_class = CurrencyDisplayConfig
|
|
27
|
+
title_config_class = CurrencyTitleConfig
|
|
28
|
+
preview_config_class = CurrencyPreviewConfig
|
|
29
|
+
|
|
30
|
+
queryset = Currency.objects.all()
|
|
31
|
+
serializer_class = CurrencyModelSerializer
|
|
32
|
+
|
|
33
|
+
filter_backends = (DjangoFilterBackend, filters.OrderingFilter)
|
|
34
|
+
|
|
35
|
+
filterset_fields = {
|
|
36
|
+
"title": ["exact", "icontains"],
|
|
37
|
+
"symbol": ["exact", "icontains"],
|
|
38
|
+
"key": ["exact", "icontains"],
|
|
39
|
+
}
|
|
40
|
+
ordering_fields = ("title", "symbol", "key")
|
|
41
|
+
|
|
42
|
+
ordering = ["title"]
|
|
43
|
+
|
|
44
|
+
def get_queryset(self):
|
|
45
|
+
last_rate_date = date.today()
|
|
46
|
+
if CurrencyFXRates.objects.exists():
|
|
47
|
+
last_rate_date = CurrencyFXRates.objects.latest("date").date
|
|
48
|
+
last_rate_date -= timedelta(days=30)
|
|
49
|
+
return (
|
|
50
|
+
super()
|
|
51
|
+
.get_queryset()
|
|
52
|
+
.annotate(
|
|
53
|
+
fx_rates_date=ArrayAgg("fx_rates__date", filter=Q(fx_rates__date__gt=last_rate_date)),
|
|
54
|
+
fx_rates_value=ArrayAgg("fx_rates__value", filter=Q(fx_rates__date__gt=last_rate_date)),
|
|
55
|
+
)
|
|
56
|
+
)
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
from rest_framework import filters
|
|
2
|
+
from wbcore import viewsets
|
|
3
|
+
from wbcore.filters import DjangoFilterBackend
|
|
4
|
+
|
|
5
|
+
from ..models import CurrencyFXRates
|
|
6
|
+
from ..serializers import CurrencyFXRatesModelSerializer
|
|
7
|
+
from .display import CurrencyFXRatesCurrencyDisplayConfig
|
|
8
|
+
from .endpoints import CurrencyFXRatesCurrencyEndpointConfig
|
|
9
|
+
from .titles import CurrencyFXRatesCurrencyTitleConfig
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class CurrencyFXRatesCurrencyModelViewSet(viewsets.ModelViewSet):
|
|
13
|
+
display_config_class = CurrencyFXRatesCurrencyDisplayConfig
|
|
14
|
+
endpoint_config_class = CurrencyFXRatesCurrencyEndpointConfig
|
|
15
|
+
title_config_class = CurrencyFXRatesCurrencyTitleConfig
|
|
16
|
+
|
|
17
|
+
serializer_class = CurrencyFXRatesModelSerializer
|
|
18
|
+
filter_backends = (filters.OrderingFilter, DjangoFilterBackend)
|
|
19
|
+
|
|
20
|
+
ordering = ordering_fields = ["-date"]
|
|
21
|
+
|
|
22
|
+
filter_backends = (DjangoFilterBackend, filters.OrderingFilter)
|
|
23
|
+
queryset = CurrencyFXRates.objects.all()
|
|
24
|
+
|
|
25
|
+
filterset_fields = {"date": ["gte", "exact", "lte"], "value": ["gte", "exact", "lte"]}
|
|
26
|
+
ordering_fields = ("date", "value")
|
|
27
|
+
|
|
28
|
+
ordering = ["-date"]
|
|
29
|
+
|
|
30
|
+
def get_queryset(self):
|
|
31
|
+
_id = self.kwargs["currency_id"]
|
|
32
|
+
return CurrencyFXRates.objects.filter(currency__id=_id).all()
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
3
|
+
from django.utils.translation import gettext_lazy as _
|
|
4
|
+
from wbcore.metadata.configs import display as dp
|
|
5
|
+
from wbcore.metadata.configs.display.instance_display.shortcuts import (
|
|
6
|
+
Display,
|
|
7
|
+
create_simple_display,
|
|
8
|
+
create_simple_section,
|
|
9
|
+
)
|
|
10
|
+
from wbcore.metadata.configs.display.instance_display.utils import repeat_field
|
|
11
|
+
from wbcore.metadata.configs.display.view_config import DisplayViewConfig
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class CurrencyDisplayConfig(DisplayViewConfig):
|
|
15
|
+
def get_list_display(self) -> Optional[dp.ListDisplay]:
|
|
16
|
+
return dp.ListDisplay(
|
|
17
|
+
fields=[
|
|
18
|
+
dp.Field(key="title", label="Title"),
|
|
19
|
+
dp.Field(key="symbol", label="Sybmol"),
|
|
20
|
+
dp.Field(key="key", label="Key"),
|
|
21
|
+
dp.Field(key="rates_sparkline", label="Rates"),
|
|
22
|
+
]
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
def get_instance_display(self) -> Display:
|
|
26
|
+
return create_simple_display(
|
|
27
|
+
[["title", "symbol", "key"], [repeat_field(3, "currencyfxrates_section")]],
|
|
28
|
+
[
|
|
29
|
+
create_simple_section(
|
|
30
|
+
"currencyfxrates_section",
|
|
31
|
+
_("Rates"),
|
|
32
|
+
[["currency_currencyfxrates"]],
|
|
33
|
+
"currency_currencyfxrates",
|
|
34
|
+
collapsed=False,
|
|
35
|
+
)
|
|
36
|
+
],
|
|
37
|
+
)
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
3
|
+
from wbcore.metadata.configs import display as dp
|
|
4
|
+
from wbcore.metadata.configs.display.view_config import DisplayViewConfig
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class CurrencyFXRatesCurrencyDisplayConfig(DisplayViewConfig):
|
|
8
|
+
def get_list_display(self) -> Optional[dp.ListDisplay]:
|
|
9
|
+
return dp.ListDisplay(fields=[dp.Field(key="date", label="Date"), dp.Field(key="value", label="Value")])
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .currency_fx_rates import CurrencyFXRatesCurrencyEndpointConfig
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
from rest_framework.reverse import reverse
|
|
2
|
+
from wbcore.metadata.configs.endpoints import EndpointViewConfig
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class CurrencyFXRatesCurrencyEndpointConfig(EndpointViewConfig):
|
|
6
|
+
def get_endpoint(self, **kwargs):
|
|
7
|
+
return None
|
|
8
|
+
|
|
9
|
+
def get_list_endpoint(self, **kwargs):
|
|
10
|
+
return reverse(
|
|
11
|
+
"wbcore:currency:currency-currencyfxrates-list",
|
|
12
|
+
args=[self.view.kwargs["currency_id"]],
|
|
13
|
+
request=self.request,
|
|
14
|
+
)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .currency import CURRENCY_MENUITEM
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
from wbcore.menus import ItemPermission, MenuItem
|
|
2
|
+
|
|
3
|
+
CURRENCY_MENUITEM = MenuItem(
|
|
4
|
+
label="Currency",
|
|
5
|
+
endpoint="wbcore:currency:currency-list",
|
|
6
|
+
add=MenuItem(label="New Currency", endpoint="wbcore:currency:currency-list"),
|
|
7
|
+
permission=ItemPermission(method=lambda request: request.user.is_staff),
|
|
8
|
+
)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .currency import CurrencyPreviewConfig
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
from wbcore.metadata.configs.display.instance_display.shortcuts import (
|
|
2
|
+
Display,
|
|
3
|
+
create_simple_display,
|
|
4
|
+
)
|
|
5
|
+
from wbcore.metadata.configs.preview import PreviewViewConfig
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class CurrencyPreviewConfig(PreviewViewConfig):
|
|
9
|
+
def get_display(self) -> Display:
|
|
10
|
+
return create_simple_display([["title", "symbol", "key"]])
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
from wbcore.contrib.currency.models import Currency
|
|
2
|
+
from wbcore.metadata.configs.titles import TitleViewConfig
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class CurrencyFXRatesCurrencyTitleConfig(TitleViewConfig):
|
|
6
|
+
def get_list_title(self):
|
|
7
|
+
currency = Currency.objects.get(id=self.view.kwargs["currency_id"])
|
|
8
|
+
return f"Rates for {currency.key} ({currency.symbol})"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "1.0.0"
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
from typing import TYPE_CHECKING, Generator
|
|
2
|
+
|
|
3
|
+
if TYPE_CHECKING:
|
|
4
|
+
from django.db.models import QuerySet
|
|
5
|
+
from wbcore.contrib.dataloader.models.entities import Entity
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class Dataloader:
|
|
9
|
+
"""Base class for dataloaders, providing a foundational structure for subclasses.
|
|
10
|
+
|
|
11
|
+
This class includes an attribute `entities`, which is a Django queryset of Entity objects.
|
|
12
|
+
It is designed to be subclassed by other classes which will implement specific methods.
|
|
13
|
+
|
|
14
|
+
Attributes:
|
|
15
|
+
entities (QuerySet[Entity]): A Django queryset of Entity objects.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
def __init__(self, entities: "QuerySet[Entity]"):
|
|
19
|
+
self.entities = entities
|
|
20
|
+
super().__init__()
|
|
21
|
+
|
|
22
|
+
@property
|
|
23
|
+
def entity_ids(self) -> Generator[int, None, None]:
|
|
24
|
+
return self.entities.values_list("id", flat=True)
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
from contextlib import suppress
|
|
2
|
+
from typing import TYPE_CHECKING, Generic, Iterator, Type, TypeVar
|
|
3
|
+
|
|
4
|
+
from django.utils.module_loading import import_string
|
|
5
|
+
|
|
6
|
+
if TYPE_CHECKING:
|
|
7
|
+
from django.db.models import QuerySet
|
|
8
|
+
from wbcore.contrib.dataloader.dataloaders import Dataloader
|
|
9
|
+
from wbcore.contrib.dataloader.models import Entity
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
T = TypeVar("T")
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class DataloaderProxy(Generic[T]):
|
|
16
|
+
"""Manages and facilitates data loading from remote resources using dataloaders.
|
|
17
|
+
|
|
18
|
+
This class serves as a proxy for various dataloader instances. Each dataloader is
|
|
19
|
+
a subclass of `Dataloader`, designed to fetch data from a remote resource. The
|
|
20
|
+
`DataloaderProxy` class enables the splicing of a queryset into parts, where each
|
|
21
|
+
part uses a specific dataloader, thus abstracting the complexity of data fetching
|
|
22
|
+
from multiple sources.
|
|
23
|
+
|
|
24
|
+
The key responsibility of this class includes:
|
|
25
|
+
- Splicing a queryset into segments, ensuring each segment uses the corresponding dataloader.
|
|
26
|
+
- Providing an external interface to interact with different dataloaders, which allows
|
|
27
|
+
for efficient data retrieval and processing.
|
|
28
|
+
|
|
29
|
+
To utilize this class, it should be subclassed and associated with a Django model
|
|
30
|
+
that can be processed by the `Dataloader` subclasses. This setup facilitates the
|
|
31
|
+
dynamic and efficient retrieval of data, tailored to the specific needs of the application.
|
|
32
|
+
|
|
33
|
+
Attributes:
|
|
34
|
+
queryset (QuerySet[Entity]): A Django queryset that represents a collection of
|
|
35
|
+
entities to be processed by the dataloaders.
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
def __init__(self, queryset: "QuerySet[Entity]"):
|
|
39
|
+
self.queryset = queryset
|
|
40
|
+
|
|
41
|
+
@staticmethod
|
|
42
|
+
def load_dataloader(path: str) -> Type["Dataloader"]:
|
|
43
|
+
"""Loads a Dataloader object from a given path.
|
|
44
|
+
|
|
45
|
+
This static method imports a Dataloader class from the specified path string.
|
|
46
|
+
|
|
47
|
+
Args:
|
|
48
|
+
path (str): The dot-delimited path to the Dataloader class to be imported.
|
|
49
|
+
For example, 'module.submodule.ClassName'.
|
|
50
|
+
|
|
51
|
+
Returns:
|
|
52
|
+
Type["Dataloader"]: An instance of the Dataloader class loaded from the given path.
|
|
53
|
+
|
|
54
|
+
Raises:
|
|
55
|
+
ImportError: If the path does not correspond to a valid class.
|
|
56
|
+
"""
|
|
57
|
+
return import_string(path)
|
|
58
|
+
|
|
59
|
+
def iterate_dataloaders(self, dl_name: str) -> Iterator[T]:
|
|
60
|
+
"""Iterates over distinct dataloaders specified by a given name.
|
|
61
|
+
|
|
62
|
+
This method retrieves a distinct list of paths associated with the specified
|
|
63
|
+
dataloader name, then iterates over these paths. For each path, it loads a
|
|
64
|
+
dataloader instance and filters the queryset based on the path, then yields
|
|
65
|
+
this dataloader.
|
|
66
|
+
|
|
67
|
+
The type `T` represents the specific type of the dataloaders that will be loaded and
|
|
68
|
+
iterated over.
|
|
69
|
+
|
|
70
|
+
Args:
|
|
71
|
+
dl_name (str): The name of the dataloader to be iterated over. This name
|
|
72
|
+
is used to construct the path key for querying distinct dataloader paths.
|
|
73
|
+
|
|
74
|
+
Returns:
|
|
75
|
+
Iterator[T]: An iterator of dataloader instances of the generic type `T` corresponding
|
|
76
|
+
to each distinct path found in the queryset.
|
|
77
|
+
"""
|
|
78
|
+
dl_path = f"dl_parameters__{dl_name}__path"
|
|
79
|
+
for path in self.queryset.distinct(dl_path).values_list(dl_path, flat=True):
|
|
80
|
+
with suppress(AttributeError):
|
|
81
|
+
yield self.load_dataloader(path)(self.queryset.filter(**{dl_path: path}))
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .entities import Entity
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
from django.db import models
|
|
2
|
+
from wbcore.contrib.dataloader.dataloaders import DataloaderProxy
|
|
3
|
+
from wbcore.contrib.dataloader.models.querysets import EntityQuerySet
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Entity(models.Model):
|
|
7
|
+
"""An abstract model representing an entity with associated dataloaders.
|
|
8
|
+
|
|
9
|
+
This model serves as a base for entities that store data and have dataloaders
|
|
10
|
+
attached for data retrieval and processing. It includes specialized fields to
|
|
11
|
+
facilitate the use of dataloaders:
|
|
12
|
+
|
|
13
|
+
Attributes:
|
|
14
|
+
dl_proxy (DataloaderProxy): A reference to the DataloaderProxy. This should be
|
|
15
|
+
set when using this model to manage the associated dataloaders.
|
|
16
|
+
dl_parameters (models.JSONField): A field to store parameters for various
|
|
17
|
+
dataloaders. It is structured in the format:
|
|
18
|
+
`{"dataloader_name": {"path": "path.to.dataloader", "parameters": {}}}`.
|
|
19
|
+
objects (EntityQuerySet): A custom model manager providing an interface to a
|
|
20
|
+
dataloader proxy. This proxy can be accessed through the 'dl' method on a
|
|
21
|
+
queryset, e.g., `Entity.objects.all().dl`.
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
dl_proxy: DataloaderProxy
|
|
25
|
+
dl_parameters = models.JSONField(default=dict, blank=True)
|
|
26
|
+
objects = EntityQuerySet.as_manager()
|
|
27
|
+
|
|
28
|
+
class Meta:
|
|
29
|
+
abstract = True
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .entities import EntityQuerySet
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
from django.db import models
|
|
2
|
+
from wbcore.contrib.dataloader.dataloaders.proxies import DataloaderProxy
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class EntityQuerySet(models.QuerySet):
|
|
6
|
+
"""A custom QuerySet for entities that provides an interface to a dataloader proxy.
|
|
7
|
+
|
|
8
|
+
This QuerySet subclass adds a method to interact with the associated dataloader
|
|
9
|
+
proxy. It is designed to be used with models that inherit from the `Entity` class,
|
|
10
|
+
providing a streamlined way to access dataloader functionality directly from
|
|
11
|
+
QuerySet instances.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
@property
|
|
15
|
+
def dl(self) -> DataloaderProxy:
|
|
16
|
+
"""Provides access to the dataloader proxy for the entities in the QuerySet.
|
|
17
|
+
|
|
18
|
+
This method allows for easy retrieval of the DataloaderProxy instance
|
|
19
|
+
associated with the QuerySet. It enables the utilization of dataloader
|
|
20
|
+
functionalities directly from the QuerySet, facilitating data fetching and
|
|
21
|
+
processing tasks.
|
|
22
|
+
|
|
23
|
+
Returns:
|
|
24
|
+
DataloaderProxy: An instance of DataloaderProxy associated with the
|
|
25
|
+
entities in the QuerySet.
|
|
26
|
+
"""
|
|
27
|
+
return self.model.dl_proxy(self)
|
|
File without changes
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
from django.db import connection
|
|
2
|
+
from django.db.models.signals import pre_migrate
|
|
3
|
+
from pytest_factoryboy import register
|
|
4
|
+
|
|
5
|
+
from .test.factories import EntityTestFactory
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def app_pre_migration(sender, app_config, **kwargs):
|
|
9
|
+
cur = connection.cursor()
|
|
10
|
+
cur.execute("CREATE EXTENSION IF NOT EXISTS pg_trgm;")
|
|
11
|
+
cur.execute("CREATE EXTENSION IF NOT EXISTS btree_gin;")
|
|
12
|
+
cur.execute("CREATE EXTENSION IF NOT EXISTS btree_gist;")
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
pre_migrate.connect(app_pre_migration)
|
|
16
|
+
register(EntityTestFactory)
|
|
17
|
+
register(
|
|
18
|
+
EntityTestFactory,
|
|
19
|
+
"entity_test_over_1000",
|
|
20
|
+
dl_parameters={
|
|
21
|
+
"data": {
|
|
22
|
+
"path": "wbcore.contrib.dataloader.tests.test.dataloaders.dataloaders.RandomDataOver1000",
|
|
23
|
+
"parameters": {},
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
)
|
|
File without changes
|
|
File without changes
|