diff --git a/config/__pycache__/__init__.cpython-311.pyc b/config/__pycache__/__init__.cpython-311.pyc index abb9e5e..dbdb7f7 100644 Binary files a/config/__pycache__/__init__.cpython-311.pyc and b/config/__pycache__/__init__.cpython-311.pyc differ diff --git a/config/__pycache__/settings.cpython-311.pyc b/config/__pycache__/settings.cpython-311.pyc index 378bb12..7f1a2ce 100644 Binary files a/config/__pycache__/settings.cpython-311.pyc and b/config/__pycache__/settings.cpython-311.pyc differ diff --git a/config/__pycache__/urls.cpython-311.pyc b/config/__pycache__/urls.cpython-311.pyc index d1a5bd9..0360cfc 100644 Binary files a/config/__pycache__/urls.cpython-311.pyc and b/config/__pycache__/urls.cpython-311.pyc differ diff --git a/config/__pycache__/wsgi.cpython-311.pyc b/config/__pycache__/wsgi.cpython-311.pyc index dc8fc90..37b87e9 100644 Binary files a/config/__pycache__/wsgi.cpython-311.pyc and b/config/__pycache__/wsgi.cpython-311.pyc differ diff --git a/core/__pycache__/__init__.cpython-311.pyc b/core/__pycache__/__init__.cpython-311.pyc index 8e9fc3d..e6c2d7a 100644 Binary files a/core/__pycache__/__init__.cpython-311.pyc and b/core/__pycache__/__init__.cpython-311.pyc differ diff --git a/core/__pycache__/admin.cpython-311.pyc b/core/__pycache__/admin.cpython-311.pyc index 42ebf60..8bc6680 100644 Binary files a/core/__pycache__/admin.cpython-311.pyc and b/core/__pycache__/admin.cpython-311.pyc differ diff --git a/core/__pycache__/apps.cpython-311.pyc b/core/__pycache__/apps.cpython-311.pyc index 1c28907..d00627a 100644 Binary files a/core/__pycache__/apps.cpython-311.pyc and b/core/__pycache__/apps.cpython-311.pyc differ diff --git a/core/__pycache__/context_processors.cpython-311.pyc b/core/__pycache__/context_processors.cpython-311.pyc index db70f1c..b51dae1 100644 Binary files a/core/__pycache__/context_processors.cpython-311.pyc and b/core/__pycache__/context_processors.cpython-311.pyc differ diff --git a/core/__pycache__/forms.cpython-311.pyc b/core/__pycache__/forms.cpython-311.pyc index 7204cbf..112c768 100644 Binary files a/core/__pycache__/forms.cpython-311.pyc and b/core/__pycache__/forms.cpython-311.pyc differ diff --git a/core/__pycache__/models.cpython-311.pyc b/core/__pycache__/models.cpython-311.pyc index cd00605..fd404a0 100644 Binary files a/core/__pycache__/models.cpython-311.pyc and b/core/__pycache__/models.cpython-311.pyc differ diff --git a/core/__pycache__/urls.cpython-311.pyc b/core/__pycache__/urls.cpython-311.pyc index 198b087..dbb02d1 100644 Binary files a/core/__pycache__/urls.cpython-311.pyc and b/core/__pycache__/urls.cpython-311.pyc differ diff --git a/core/__pycache__/views.cpython-311.pyc b/core/__pycache__/views.cpython-311.pyc index aeea159..3d561f0 100644 Binary files a/core/__pycache__/views.cpython-311.pyc and b/core/__pycache__/views.cpython-311.pyc differ diff --git a/core/management/__pycache__/__init__.cpython-311.pyc b/core/management/__pycache__/__init__.cpython-311.pyc index 80f2921..5f51627 100644 Binary files a/core/management/__pycache__/__init__.cpython-311.pyc and b/core/management/__pycache__/__init__.cpython-311.pyc differ diff --git a/core/migrations/__pycache__/0001_initial.cpython-311.pyc b/core/migrations/__pycache__/0001_initial.cpython-311.pyc index c162e57..bd2b374 100644 Binary files a/core/migrations/__pycache__/0001_initial.cpython-311.pyc and b/core/migrations/__pycache__/0001_initial.cpython-311.pyc differ diff --git a/core/migrations/__pycache__/0002_bloodbank_contact_number_bloodbank_is_24_7_and_more.cpython-311.pyc b/core/migrations/__pycache__/0002_bloodbank_contact_number_bloodbank_is_24_7_and_more.cpython-311.pyc index b20e5ab..5afcc90 100644 Binary files a/core/migrations/__pycache__/0002_bloodbank_contact_number_bloodbank_is_24_7_and_more.cpython-311.pyc and b/core/migrations/__pycache__/0002_bloodbank_contact_number_bloodbank_is_24_7_and_more.cpython-311.pyc differ diff --git a/core/migrations/__pycache__/0003_donor_citizenship_no_donor_district_and_more.cpython-311.pyc b/core/migrations/__pycache__/0003_donor_citizenship_no_donor_district_and_more.cpython-311.pyc index 05ff597..b6002f4 100644 Binary files a/core/migrations/__pycache__/0003_donor_citizenship_no_donor_district_and_more.cpython-311.pyc and b/core/migrations/__pycache__/0003_donor_citizenship_no_donor_district_and_more.cpython-311.pyc differ diff --git a/core/migrations/__pycache__/0004_vaccinerecord.cpython-311.pyc b/core/migrations/__pycache__/0004_vaccinerecord.cpython-311.pyc index 2dabec1..554916b 100644 Binary files a/core/migrations/__pycache__/0004_vaccinerecord.cpython-311.pyc and b/core/migrations/__pycache__/0004_vaccinerecord.cpython-311.pyc differ diff --git a/core/migrations/__pycache__/0005_bloodbank_latitude_bloodbank_longitude.cpython-311.pyc b/core/migrations/__pycache__/0005_bloodbank_latitude_bloodbank_longitude.cpython-311.pyc index e1a0ddd..93873a5 100644 Binary files a/core/migrations/__pycache__/0005_bloodbank_latitude_bloodbank_longitude.cpython-311.pyc and b/core/migrations/__pycache__/0005_bloodbank_latitude_bloodbank_longitude.cpython-311.pyc differ diff --git a/core/migrations/__pycache__/0006_bloodrequest_latitude_bloodrequest_longitude.cpython-311.pyc b/core/migrations/__pycache__/0006_bloodrequest_latitude_bloodrequest_longitude.cpython-311.pyc index 144b2a2..fcb3ed8 100644 Binary files a/core/migrations/__pycache__/0006_bloodrequest_latitude_bloodrequest_longitude.cpython-311.pyc and b/core/migrations/__pycache__/0006_bloodrequest_latitude_bloodrequest_longitude.cpython-311.pyc differ diff --git a/core/migrations/__pycache__/0007_bloodbank_total_capacity.cpython-311.pyc b/core/migrations/__pycache__/0007_bloodbank_total_capacity.cpython-311.pyc index 120d712..85af265 100644 Binary files a/core/migrations/__pycache__/0007_bloodbank_total_capacity.cpython-311.pyc and b/core/migrations/__pycache__/0007_bloodbank_total_capacity.cpython-311.pyc differ diff --git a/core/migrations/__pycache__/0008_userprofile.cpython-311.pyc b/core/migrations/__pycache__/0008_userprofile.cpython-311.pyc index 6c0e3a7..ac6e64f 100644 Binary files a/core/migrations/__pycache__/0008_userprofile.cpython-311.pyc and b/core/migrations/__pycache__/0008_userprofile.cpython-311.pyc differ diff --git a/core/migrations/__pycache__/0009_bloodrequest_user_donor_user_donationevent_feedback_and_more.cpython-311.pyc b/core/migrations/__pycache__/0009_bloodrequest_user_donor_user_donationevent_feedback_and_more.cpython-311.pyc index 0431d83..b85a887 100644 Binary files a/core/migrations/__pycache__/0009_bloodrequest_user_donor_user_donationevent_feedback_and_more.cpython-311.pyc and b/core/migrations/__pycache__/0009_bloodrequest_user_donor_user_donationevent_feedback_and_more.cpython-311.pyc differ diff --git a/core/migrations/__pycache__/0010_delete_feedback.cpython-311.pyc b/core/migrations/__pycache__/0010_delete_feedback.cpython-311.pyc index adbdc32..f2173e0 100644 Binary files a/core/migrations/__pycache__/0010_delete_feedback.cpython-311.pyc and b/core/migrations/__pycache__/0010_delete_feedback.cpython-311.pyc differ diff --git a/core/migrations/__pycache__/0011_hospital.cpython-311.pyc b/core/migrations/__pycache__/0011_hospital.cpython-311.pyc index bab95c1..78740f7 100644 Binary files a/core/migrations/__pycache__/0011_hospital.cpython-311.pyc and b/core/migrations/__pycache__/0011_hospital.cpython-311.pyc differ diff --git a/core/migrations/__pycache__/0012_hospital_latitude_hospital_longitude.cpython-311.pyc b/core/migrations/__pycache__/0012_hospital_latitude_hospital_longitude.cpython-311.pyc index 6039d83..dc37c8a 100644 Binary files a/core/migrations/__pycache__/0012_hospital_latitude_hospital_longitude.cpython-311.pyc and b/core/migrations/__pycache__/0012_hospital_latitude_hospital_longitude.cpython-311.pyc differ diff --git a/core/migrations/__pycache__/0013_userprofile_profile_pic.cpython-311.pyc b/core/migrations/__pycache__/0013_userprofile_profile_pic.cpython-311.pyc index 6041900..a00251c 100644 Binary files a/core/migrations/__pycache__/0013_userprofile_profile_pic.cpython-311.pyc and b/core/migrations/__pycache__/0013_userprofile_profile_pic.cpython-311.pyc differ diff --git a/core/migrations/__pycache__/0014_message.cpython-311.pyc b/core/migrations/__pycache__/0014_message.cpython-311.pyc index 7665b75..943b4de 100644 Binary files a/core/migrations/__pycache__/0014_message.cpython-311.pyc and b/core/migrations/__pycache__/0014_message.cpython-311.pyc differ diff --git a/core/migrations/__pycache__/0015_userprofile_last_location_update_and_more.cpython-311.pyc b/core/migrations/__pycache__/0015_userprofile_last_location_update_and_more.cpython-311.pyc index 09409a5..f9b6cb9 100644 Binary files a/core/migrations/__pycache__/0015_userprofile_last_location_update_and_more.cpython-311.pyc and b/core/migrations/__pycache__/0015_userprofile_last_location_update_and_more.cpython-311.pyc differ diff --git a/core/migrations/__pycache__/0016_badge_userprofile_badges.cpython-311.pyc b/core/migrations/__pycache__/0016_badge_userprofile_badges.cpython-311.pyc index 83b2863..83c38f0 100644 Binary files a/core/migrations/__pycache__/0016_badge_userprofile_badges.cpython-311.pyc and b/core/migrations/__pycache__/0016_badge_userprofile_badges.cpython-311.pyc differ diff --git a/core/migrations/__pycache__/0017_message_attachment_message_message_type_and_more.cpython-311.pyc b/core/migrations/__pycache__/0017_message_attachment_message_message_type_and_more.cpython-311.pyc index 1c00a37..b971bd1 100644 Binary files a/core/migrations/__pycache__/0017_message_attachment_message_message_type_and_more.cpython-311.pyc and b/core/migrations/__pycache__/0017_message_attachment_message_message_type_and_more.cpython-311.pyc differ diff --git a/core/migrations/__pycache__/0018_bloodrequest_image.cpython-311.pyc b/core/migrations/__pycache__/0018_bloodrequest_image.cpython-311.pyc index 89cd3cb..e21f244 100644 Binary files a/core/migrations/__pycache__/0018_bloodrequest_image.cpython-311.pyc and b/core/migrations/__pycache__/0018_bloodrequest_image.cpython-311.pyc differ diff --git a/core/migrations/__pycache__/0019_healthreport.cpython-311.pyc b/core/migrations/__pycache__/0019_healthreport.cpython-311.pyc index b85f3ca..ed4dce3 100644 Binary files a/core/migrations/__pycache__/0019_healthreport.cpython-311.pyc and b/core/migrations/__pycache__/0019_healthreport.cpython-311.pyc differ diff --git a/core/migrations/__pycache__/0020_vaccinerecord_photo.cpython-311.pyc b/core/migrations/__pycache__/0020_vaccinerecord_photo.cpython-311.pyc index 4080729..221ee02 100644 Binary files a/core/migrations/__pycache__/0020_vaccinerecord_photo.cpython-311.pyc and b/core/migrations/__pycache__/0020_vaccinerecord_photo.cpython-311.pyc differ diff --git a/core/migrations/__pycache__/0021_bloodrequest_accepted_at.cpython-311.pyc b/core/migrations/__pycache__/0021_bloodrequest_accepted_at.cpython-311.pyc index f83dd3d..f02c6a9 100644 Binary files a/core/migrations/__pycache__/0021_bloodrequest_accepted_at.cpython-311.pyc and b/core/migrations/__pycache__/0021_bloodrequest_accepted_at.cpython-311.pyc differ diff --git a/core/migrations/__pycache__/__init__.cpython-311.pyc b/core/migrations/__pycache__/__init__.cpython-311.pyc index c33b24d..947a927 100644 Binary files a/core/migrations/__pycache__/__init__.cpython-311.pyc and b/core/migrations/__pycache__/__init__.cpython-311.pyc differ diff --git a/core/templates/core/index.html b/core/templates/core/index.html index 1fc249b..2364f19 100644 --- a/core/templates/core/index.html +++ b/core/templates/core/index.html @@ -197,6 +197,21 @@ {% endif %} + + {% if user.username == 'demo_user' %} +
+
+
+ +
+
+
Demo Mode Active
+

You are logged in as a Demo User. Explore the platform's features, but note that some real-world integrations like SMS are simulated.

+
+
+
+ {% endif %} + {% if involved_events %}
@@ -681,4 +696,4 @@ } } -{% endblock %} +{% endblock %} \ No newline at end of file diff --git a/core/templates/core/login.html b/core/templates/core/login.html index e08b46a..d80e727 100644 --- a/core/templates/core/login.html +++ b/core/templates/core/login.html @@ -15,6 +15,16 @@

{% trans "Secure access for registered members" %}

+ +
+
+ +
+ Demo Mode Active: Use demo_user / demo1234 +
+
+
+ {% if form.non_field_errors %}
{% for error in form.non_field_errors %} @@ -26,7 +36,7 @@
{% endif %} -
+ {% csrf_token %} {% for field in form %}
@@ -50,9 +60,15 @@ Forgot password?
- +
+ + + +
@@ -66,6 +82,19 @@
+ + + {% endif %} +{% endblock %} + +{% block extrahead %} +{{ block.super }} +{{ media.js }} + +{% endblock %} + +{% block bodyclass %}{{ block.super }} app-{{ opts.app_label }} model-{{ opts.model_name }} change-list{% endblock %} + +{% if not is_popup %} +{% block breadcrumbs %} + +{% endblock %} +{% endif %} + +{% block coltype %}{% endblock %} + +{% block content %} +
+ {% block object-tools %} + + {% endblock %} + {% if cl.formset and cl.formset.errors %} +

+ {% blocktranslate count counter=cl.formset.total_error_count %}Please correct the error below.{% plural %}Please correct the errors below.{% endblocktranslate %} +

+ {{ cl.formset.non_form_errors }} + {% endif %} +
+
+ {% block search %}{% search_form cl %}{% endblock %} + {% block date_hierarchy %}{% if cl.date_hierarchy %}{% date_hierarchy cl %}{% endif %}{% endblock %} + +
{% csrf_token %} + {% if cl.formset %} +
{{ cl.formset.management_form }}
+ {% endif %} + + {% block result_list %} + {% if action_form and actions_on_top and cl.show_admin_actions %}{% admin_actions %}{% endif %} + {% result_list cl %} + {% if action_form and actions_on_bottom and cl.show_admin_actions %}{% admin_actions %}{% endif %} + {% endblock %} + {% block pagination %}{% pagination cl %}{% endblock %} +
+
+ {% block filters %} + {% if cl.has_filters %} + + {% endif %} + {% endblock %} +
+
+{% endblock %} diff --git a/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/change_list_object_tools.html b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/change_list_object_tools.html new file mode 100644 index 0000000..11cc6fa --- /dev/null +++ b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/change_list_object_tools.html @@ -0,0 +1,12 @@ +{% load i18n admin_urls %} + +{% block object-tools-items %} + {% if has_add_permission %} +
  • + {% url cl.opts|admin_urlname:'add' as add_url %} + + {% blocktranslate with cl.opts.verbose_name as name %}Add {{ name }}{% endblocktranslate %} + +
  • + {% endif %} +{% endblock %} diff --git a/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/change_list_results.html b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/change_list_results.html new file mode 100644 index 0000000..d2a9fee --- /dev/null +++ b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/change_list_results.html @@ -0,0 +1,36 @@ +{% load i18n %} +{% if result_hidden_fields %} +
    {# DIV for HTML validation #} +{% for item in result_hidden_fields %}{{ item }}{% endfor %} +
    +{% endif %} +{% if results %} +
    + + + +{% for header in result_headers %} +{% endfor %} + + + +{% for result in results %} +{% if result.form and result.form.non_field_errors %} + +{% endif %} +{% for item in result %}{{ item }}{% endfor %} +{% endfor %} + +
    + {% if header.sortable and header.sort_priority > 0 %} +
    + + {% if num_sorted_fields > 1 %}{{ header.sort_priority }}{% endif %} + +
    + {% endif %} +
    {% if header.sortable %}{{ header.text|capfirst }}{% else %}{{ header.text|capfirst }}{% endif %}
    +
    +
    {{ result.form.non_field_errors }}
    +
    +{% endif %} diff --git a/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/color_theme_toggle.html b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/color_theme_toggle.html new file mode 100644 index 0000000..2caa19e --- /dev/null +++ b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/color_theme_toggle.html @@ -0,0 +1,15 @@ +{% load i18n %} + diff --git a/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/date_hierarchy.html b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/date_hierarchy.html new file mode 100644 index 0000000..c508856 --- /dev/null +++ b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/date_hierarchy.html @@ -0,0 +1,14 @@ +{% if show %} + +{% endif %} diff --git a/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/delete_confirmation.html b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/delete_confirmation.html new file mode 100644 index 0000000..09e25e1 --- /dev/null +++ b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/delete_confirmation.html @@ -0,0 +1,50 @@ +{% extends "admin/base_site.html" %} +{% load i18n admin_urls static %} + +{% block extrahead %} + {{ block.super }} + {{ media }} + +{% endblock %} + +{% block bodyclass %}{{ block.super }} app-{{ opts.app_label }} model-{{ opts.model_name }} delete-confirmation{% endblock %} + +{% block breadcrumbs %} + +{% endblock %} + +{% block content %} +{% if perms_lacking %} + {% block delete_forbidden %} +

    {% blocktranslate with escaped_object=object %}Deleting the {{ object_name }} '{{ escaped_object }}' would result in deleting related objects, but your account doesn't have permission to delete the following types of objects:{% endblocktranslate %}

    + + {% endblock %} +{% elif protected %} + {% block delete_protected %} +

    {% blocktranslate with escaped_object=object %}Deleting the {{ object_name }} '{{ escaped_object }}' would require deleting the following protected related objects:{% endblocktranslate %}

    + + {% endblock %} +{% else %} + {% block delete_confirm %} +

    {% blocktranslate with escaped_object=object %}Are you sure you want to delete the {{ object_name }} "{{ escaped_object }}"? All of the following related items will be deleted:{% endblocktranslate %}

    + {% include "admin/includes/object_delete_summary.html" %} +

    {% translate "Objects" %}

    + +
    {% csrf_token %} +
    + + {% if is_popup %}{% endif %} + {% if to_field %}{% endif %} + + {% translate "No, take me back" %} +
    +
    + {% endblock %} +{% endif %} +{% endblock content %} diff --git a/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/delete_selected_confirmation.html b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/delete_selected_confirmation.html new file mode 100644 index 0000000..51b93a5 --- /dev/null +++ b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/delete_selected_confirmation.html @@ -0,0 +1,47 @@ +{% extends "admin/base_site.html" %} +{% load i18n l10n admin_urls static %} + +{% block extrahead %} + {{ block.super }} + {{ media }} + +{% endblock %} + +{% block bodyclass %}{{ block.super }} app-{{ opts.app_label }} model-{{ opts.model_name }} delete-confirmation delete-selected-confirmation{% endblock %} + +{% block breadcrumbs %} + +{% endblock %} + +{% block content %} +{% if perms_lacking %} +

    {% blocktranslate %}Deleting the selected {{ objects_name }} would result in deleting related objects, but your account doesn't have permission to delete the following types of objects:{% endblocktranslate %}

    + +{% elif protected %} +

    {% blocktranslate %}Deleting the selected {{ objects_name }} would require deleting the following protected related objects:{% endblocktranslate %}

    + +{% else %} +

    {% blocktranslate %}Are you sure you want to delete the selected {{ objects_name }}? All of the following objects and their related items will be deleted:{% endblocktranslate %}

    + {% include "admin/includes/object_delete_summary.html" %} +

    {% translate "Objects" %}

    + {% for deletable_object in deletable_objects %} + + {% endfor %} +
    {% csrf_token %} +
    + {% for obj in queryset %} + + {% endfor %} + + + + {% translate "No, take me back" %} +
    +
    +{% endif %} +{% endblock %} diff --git a/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/edit_inline/stacked.html b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/edit_inline/stacked.html new file mode 100644 index 0000000..a6939f4 --- /dev/null +++ b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/edit_inline/stacked.html @@ -0,0 +1,38 @@ +{% load i18n admin_urls %} +
    +
    + {% if inline_admin_formset.is_collapsible %}
    {% endif %} +

    + {% if inline_admin_formset.formset.max_num == 1 %} + {{ inline_admin_formset.opts.verbose_name|capfirst }} + {% else %} + {{ inline_admin_formset.opts.verbose_name_plural|capfirst }} + {% endif %} +

    + {% if inline_admin_formset.is_collapsible %}
    {% endif %} +{{ inline_admin_formset.formset.management_form }} +{{ inline_admin_formset.formset.non_form_errors }} + +{% for inline_admin_form in inline_admin_formset %}
    +

    {{ inline_admin_formset.opts.verbose_name|capfirst }}: {% if inline_admin_form.original %}{{ inline_admin_form.original }}{% if inline_admin_form.model_admin.show_change_link and inline_admin_form.model_admin.has_registered_model %} {% if inline_admin_formset.has_change_permission %}{% translate "Change" %}{% else %}{% translate "View" %}{% endif %}{% endif %} +{% else %}#{{ forloop.counter }}{% endif %} + {% if inline_admin_form.show_url %}{% translate "View on site" %}{% endif %} + {% if inline_admin_formset.formset.can_delete and inline_admin_formset.has_delete_permission and inline_admin_form.original %}{{ inline_admin_form.deletion_field.field }} {{ inline_admin_form.deletion_field.label_tag }}{% endif %} +

    + {% if inline_admin_form.form.non_field_errors %}{{ inline_admin_form.form.non_field_errors }}{% endif %} + + {% with parent_counter=forloop.counter0 %} + {% for fieldset in inline_admin_form %} + {% include "admin/includes/fieldset.html" with heading_level=4 prefix=fieldset.formset.prefix id_prefix=parent_counter id_suffix=forloop.counter0 %} + {% endfor %} + {% endwith %} + + {% if inline_admin_form.needs_explicit_pk_field %}{{ inline_admin_form.pk_field.field }}{% endif %} + {% if inline_admin_form.fk_field %}{{ inline_admin_form.fk_field.field }}{% endif %} +
    {% endfor %} + {% if inline_admin_formset.is_collapsible %}
    {% endif %} +
    +
    diff --git a/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/edit_inline/tabular.html b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/edit_inline/tabular.html new file mode 100644 index 0000000..9367ac9 --- /dev/null +++ b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/edit_inline/tabular.html @@ -0,0 +1,69 @@ +{% load i18n admin_urls static admin_modify %} +
    + +
    diff --git a/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/filter.html b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/filter.html new file mode 100644 index 0000000..a6094ec --- /dev/null +++ b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/filter.html @@ -0,0 +1,12 @@ +{% load i18n %} +
    + + {% blocktranslate with filter_title=title %} By {{ filter_title }} {% endblocktranslate %} + + +
    diff --git a/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/includes/fieldset.html b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/includes/fieldset.html new file mode 100644 index 0000000..9c9b319 --- /dev/null +++ b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/includes/fieldset.html @@ -0,0 +1,39 @@ +
    + {% if fieldset.name %} + {% if fieldset.is_collapsible %}
    {% endif %} + {{ fieldset.name }} + {% if fieldset.is_collapsible %}{% endif %} + {% endif %} + {% if fieldset.description %} +
    {{ fieldset.description|safe }}
    + {% endif %} + {% for line in fieldset %} +
    + {% if line.fields|length == 1 %}{{ line.errors }}{% else %}
    {% endif %} + {% for field in line %} +
    + {% if not line.fields|length == 1 and not field.is_readonly %}{{ field.errors }}{% endif %} +
    + {% if field.is_checkbox %} + {{ field.field }}{{ field.label_tag }} + {% else %} + {{ field.label_tag }} + {% if field.is_readonly %} +
    {{ field.contents }}
    + {% else %} + {{ field.field }} + {% endif %} + {% endif %} +
    + {% if field.field.help_text %} +
    +
    {{ field.field.help_text|safe }}
    +
    + {% endif %} +
    + {% endfor %} + {% if not line.fields|length == 1 %}
    {% endif %} +
    + {% endfor %} + {% if fieldset.name and fieldset.is_collapsible %}
    {% endif %} +
    diff --git a/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/includes/object_delete_summary.html b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/includes/object_delete_summary.html new file mode 100644 index 0000000..9ad97db --- /dev/null +++ b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/includes/object_delete_summary.html @@ -0,0 +1,7 @@ +{% load i18n %} +

    {% translate "Summary" %}

    + diff --git a/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/index.html b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/index.html new file mode 100644 index 0000000..899727a --- /dev/null +++ b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/index.html @@ -0,0 +1,51 @@ +{% extends "admin/base_site.html" %} +{% load i18n static %} + +{% block extrastyle %}{{ block.super }}{% endblock %} + +{% block coltype %}colMS{% endblock %} + +{% block bodyclass %}{{ block.super }} dashboard{% endblock %} + +{% block nav-breadcrumbs %}{% endblock %} + +{% block nav-sidebar %}{% endblock %} + +{% block content %} +
    + {% include "admin/app_list.html" with app_list=app_list show_changelinks=True %} +
    +{% endblock %} + +{% block sidebar %} + +{% endblock %} diff --git a/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/invalid_setup.html b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/invalid_setup.html new file mode 100644 index 0000000..1ef7c71 --- /dev/null +++ b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/invalid_setup.html @@ -0,0 +1,13 @@ +{% extends "admin/base_site.html" %} +{% load i18n %} + +{% block breadcrumbs %} + +{% endblock %} + +{% block content %} +

    {% translate 'Something’s wrong with your database installation. Make sure the appropriate database tables have been created, and make sure the database is readable by the appropriate user.' %}

    +{% endblock %} diff --git a/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/login.html b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/login.html new file mode 100644 index 0000000..fa0dcbc --- /dev/null +++ b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/login.html @@ -0,0 +1,69 @@ +{% extends "admin/base_site.html" %} +{% load i18n static %} + +{% block title %}{% if form.errors %}{% translate "Error:" %} {% endif %}{{ block.super }}{% endblock %} +{% block extrastyle %}{{ block.super }} +{{ form.media }} +{% endblock %} + +{% block bodyclass %}{{ block.super }} login{% endblock %} + +{% block usertools %}{% endblock %} + +{% block nav-global %}{% endblock %} + +{% block nav-sidebar %}{% endblock %} + +{% block content_title %}{% endblock %} + +{% block nav-breadcrumbs %}{% endblock %} + +{% block content %} +{% if form.errors and not form.non_field_errors %} +

    +{% blocktranslate count counter=form.errors.items|length %}Please correct the error below.{% plural %}Please correct the errors below.{% endblocktranslate %} +

    +{% endif %} + +{% if form.non_field_errors %} +{% for error in form.non_field_errors %} +

    + {{ error }} +

    +{% endfor %} +{% endif %} + +
    + +{% if user.is_authenticated %} +

    +{% blocktranslate trimmed %} + You are authenticated as {{ username }}, but are not authorized to + access this page. Would you like to login to a different account? +{% endblocktranslate %} +

    +{% endif %} + +
    {% csrf_token %} +
    + {{ form.username.errors }} + {{ form.username.label_tag }} {{ form.username }} +
    +
    + {{ form.password.errors }} + {{ form.password.label_tag }} {{ form.password }} + +
    + {% url 'admin_password_reset' as password_reset_url %} + {% if password_reset_url %} + + {% endif %} +
    + +
    +
    + +
    +{% endblock %} diff --git a/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/nav_sidebar.html b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/nav_sidebar.html new file mode 100644 index 0000000..a413e23 --- /dev/null +++ b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/nav_sidebar.html @@ -0,0 +1,8 @@ +{% load i18n %} + + diff --git a/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/object_history.html b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/object_history.html new file mode 100644 index 0000000..f83984c --- /dev/null +++ b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/object_history.html @@ -0,0 +1,56 @@ +{% extends "admin/base_site.html" %} +{% load i18n admin_urls %} + +{% block breadcrumbs %} + +{% endblock %} + +{% block content %} +
    +
    + +{% if action_list %} + + + + + + + + + + {% for action in action_list %} + + + + + + {% endfor %} + +
    {% translate 'Date/time' %}{% translate 'User' %}{% translate 'Action' %}
    {{ action.action_time|date:"DATETIME_FORMAT" }}{{ action.user.get_username }}{% if action.user.get_full_name %} ({{ action.user.get_full_name }}){% endif %}{{ action.get_change_message }}
    +

    + {% if pagination_required %} + {% for i in page_range %} + {% if i == action_list.paginator.ELLIPSIS %} + {{ action_list.paginator.ELLIPSIS }} + {% elif i == action_list.number %} + {{ i }} + {% else %} + {{ i }} + {% endif %} + {% endfor %} + {% endif %} + {{ action_list.paginator.count }} {% blocktranslate count counter=action_list.paginator.count %}entry{% plural %}entries{% endblocktranslate %} +

    +{% else %} +

    {% translate 'This object doesn’t have a change history. It probably wasn’t added via this admin site.' %}

    +{% endif %} +
    +
    +{% endblock %} diff --git a/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/pagination.html b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/pagination.html new file mode 100644 index 0000000..bc3117b --- /dev/null +++ b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/pagination.html @@ -0,0 +1,12 @@ +{% load admin_list %} +{% load i18n %} +

    +{% if pagination_required %} +{% for i in page_range %} + {% paginator_number cl i %} +{% endfor %} +{% endif %} +{{ cl.result_count }} {% if cl.result_count == 1 %}{{ cl.opts.verbose_name }}{% else %}{{ cl.opts.verbose_name_plural }}{% endif %} +{% if show_all_url %}{% translate 'Show all' %}{% endif %} +{% if cl.formset and cl.result_count %}{% endif %} +

    diff --git a/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/popup_response.html b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/popup_response.html new file mode 100644 index 0000000..57a1ae3 --- /dev/null +++ b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/popup_response.html @@ -0,0 +1,10 @@ +{% load i18n static %} + + {% translate 'Popup closing…' %} + + + + diff --git a/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/prepopulated_fields_js.html b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/prepopulated_fields_js.html new file mode 100644 index 0000000..dd6e561 --- /dev/null +++ b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/prepopulated_fields_js.html @@ -0,0 +1,5 @@ +{% load static %} + diff --git a/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/search_form.html b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/search_form.html new file mode 100644 index 0000000..447b803 --- /dev/null +++ b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/search_form.html @@ -0,0 +1,20 @@ +{% load i18n static %} +{% if cl.search_fields %} +
    +{% endif %} diff --git a/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/submit_line.html b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/submit_line.html new file mode 100644 index 0000000..b2b2054 --- /dev/null +++ b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/submit_line.html @@ -0,0 +1,17 @@ +{% load i18n admin_urls %} +
    +{% block submit-row %} +{% if show_save %}{% endif %} +{% if show_save_as_new %}{% endif %} +{% if show_save_and_add_another %}{% endif %} +{% if show_save_and_continue %}{% endif %} +{% if show_close %} + {% url opts|admin_urlname:'changelist' as changelist_url %} + {% translate 'Close' %} +{% endif %} +{% if show_delete_link and original %} + {% url opts|admin_urlname:'delete' original.pk|admin_urlquote as delete_url %} + {% translate "Delete" %} +{% endif %} +{% endblock %} +
    diff --git a/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/widgets/clearable_file_input.html b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/widgets/clearable_file_input.html new file mode 100644 index 0000000..8b42f19 --- /dev/null +++ b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/widgets/clearable_file_input.html @@ -0,0 +1,6 @@ +{% if widget.is_initial %}

    {{ widget.initial_text }}: {{ widget.value }}{% if not widget.required %} + + +{% endif %}
    +{{ widget.input_text }}:{% endif %} +{% if widget.is_initial %}

    {% endif %} diff --git a/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/widgets/date.html b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/widgets/date.html new file mode 100644 index 0000000..acd5d5f --- /dev/null +++ b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/widgets/date.html @@ -0,0 +1,3 @@ +

    + {% include "django/forms/widgets/date.html" %} +

    diff --git a/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/widgets/foreign_key_raw_id.html b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/widgets/foreign_key_raw_id.html new file mode 100644 index 0000000..a6eba93 --- /dev/null +++ b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/widgets/foreign_key_raw_id.html @@ -0,0 +1,2 @@ +{% if related_url %}
    {% endif %}{% include 'django/forms/widgets/input.html' %}{% if related_url %}{% endif %}{% if link_label %} +{% if link_url %}{{ link_label }}{% else %}{{ link_label }}{% endif %}{% endif %}{% if related_url %}
    {% endif %} diff --git a/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/widgets/many_to_many_raw_id.html b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/widgets/many_to_many_raw_id.html new file mode 100644 index 0000000..0dd0331 --- /dev/null +++ b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/widgets/many_to_many_raw_id.html @@ -0,0 +1 @@ +{% include 'admin/widgets/foreign_key_raw_id.html' %} diff --git a/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/widgets/radio.html b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/widgets/radio.html new file mode 100644 index 0000000..780899a --- /dev/null +++ b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/widgets/radio.html @@ -0,0 +1 @@ +{% include "django/forms/widgets/multiple_input.html" %} diff --git a/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/widgets/related_widget_wrapper.html b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/widgets/related_widget_wrapper.html new file mode 100644 index 0000000..9251527 --- /dev/null +++ b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/widgets/related_widget_wrapper.html @@ -0,0 +1,41 @@ +{% load i18n static %} + diff --git a/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/widgets/split_datetime.html b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/widgets/split_datetime.html new file mode 100644 index 0000000..7fc7bf6 --- /dev/null +++ b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/widgets/split_datetime.html @@ -0,0 +1,4 @@ +

    + {{ date_label }} {% with widget=widget.subwidgets.0 %}{% include widget.template_name %}{% endwith %}
    + {{ time_label }} {% with widget=widget.subwidgets.1 %}{% include widget.template_name %}{% endwith %} +

    diff --git a/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/widgets/time.html b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/widgets/time.html new file mode 100644 index 0000000..e4eaca6 --- /dev/null +++ b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/widgets/time.html @@ -0,0 +1,3 @@ +

    + {% include "django/forms/widgets/time.html" %} +

    diff --git a/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/widgets/url.html b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/widgets/url.html new file mode 100644 index 0000000..69dc401 --- /dev/null +++ b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/admin/widgets/url.html @@ -0,0 +1 @@ +{% if url_valid %}

    {{ current_label }} {{ widget.value }}
    {{ change_label }} {% endif %}{% include "django/forms/widgets/input.html" %}{% if url_valid %}

    {% endif %} diff --git a/venv/lib/python3.11/site-packages/django/contrib/admin/templates/registration/logged_out.html b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/registration/logged_out.html new file mode 100644 index 0000000..e9a5545 --- /dev/null +++ b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/registration/logged_out.html @@ -0,0 +1,14 @@ +{% extends "admin/base_site.html" %} +{% load i18n %} + +{% block breadcrumbs %}{% endblock %} + +{% block nav-sidebar %}{% endblock %} + +{% block content %} + +

    {% translate "Thanks for spending some quality time with the web site today." %}

    + +

    {% translate 'Log in again' %}

    + +{% endblock %} diff --git a/venv/lib/python3.11/site-packages/django/contrib/admin/templates/registration/password_change_done.html b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/registration/password_change_done.html new file mode 100644 index 0000000..784ab37 --- /dev/null +++ b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/registration/password_change_done.html @@ -0,0 +1,20 @@ +{% extends "admin/base_site.html" %} +{% load i18n %} +{% block userlinks %} + {% url 'django-admindocs-docroot' as docsroot %}{% if docsroot %}{% translate 'Documentation' %} / {% endif %}{% translate 'Change password' %} / +
    + {% csrf_token %} + +
    + {% include "admin/color_theme_toggle.html" %} +{% endblock %} +{% block breadcrumbs %} + +{% endblock %} + +{% block content %} +

    {% translate 'Your password was changed.' %}

    +{% endblock %} diff --git a/venv/lib/python3.11/site-packages/django/contrib/admin/templates/registration/password_change_form.html b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/registration/password_change_form.html new file mode 100644 index 0000000..3d66aeb --- /dev/null +++ b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/registration/password_change_form.html @@ -0,0 +1,66 @@ +{% extends "admin/base_site.html" %} +{% load i18n static %} + +{% block title %}{% if form.errors %}{% translate "Error:" %} {% endif %}{{ block.super }}{% endblock %} +{% block extrastyle %}{{ block.super }}{% endblock %} +{% block userlinks %} + {% url 'django-admindocs-docroot' as docsroot %}{% if docsroot %}{% translate 'Documentation' %} / {% endif %} {% translate 'Change password' %} / +
    + {% csrf_token %} + +
    + {% include "admin/color_theme_toggle.html" %} +{% endblock %} +{% block breadcrumbs %} + +{% endblock %} + +{% block content %}
    + +
    {% csrf_token %} +
    +{% if form.errors %} +

    + {% blocktranslate count counter=form.errors.items|length %}Please correct the error below.{% plural %}Please correct the errors below.{% endblocktranslate %} +

    +{% endif %} + + +

    {% translate 'Please enter your old password, for security’s sake, and then enter your new password twice so we can verify you typed it in correctly.' %}

    + +
    + +
    + {{ form.old_password.errors }} +
    {{ form.old_password.label_tag }} {{ form.old_password }}
    +
    + +
    + {{ form.new_password1.errors }} +
    {{ form.new_password1.label_tag }} {{ form.new_password1 }}
    + {% if form.new_password1.help_text %} +
    {{ form.new_password1.help_text|safe }}
    + {% endif %} +
    + +
    + {{ form.new_password2.errors }} +
    {{ form.new_password2.label_tag }} {{ form.new_password2 }}
    + {% if form.new_password2.help_text %} +
    {{ form.new_password2.help_text|safe }}
    + {% endif %} +
    + +
    + +
    + +
    + +
    +
    + +{% endblock %} diff --git a/venv/lib/python3.11/site-packages/django/contrib/admin/templates/registration/password_reset_complete.html b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/registration/password_reset_complete.html new file mode 100644 index 0000000..e6a383f --- /dev/null +++ b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/registration/password_reset_complete.html @@ -0,0 +1,17 @@ +{% extends "admin/base_site.html" %} +{% load i18n %} + +{% block breadcrumbs %} + +{% endblock %} + +{% block content %} + +

    {% translate "Your password has been set. You may go ahead and log in now." %}

    + +

    {% translate 'Log in' %}

    + +{% endblock %} diff --git a/venv/lib/python3.11/site-packages/django/contrib/admin/templates/registration/password_reset_confirm.html b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/registration/password_reset_confirm.html new file mode 100644 index 0000000..5e1478b --- /dev/null +++ b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/registration/password_reset_confirm.html @@ -0,0 +1,48 @@ +{% extends "admin/base_site.html" %} +{% load i18n static %} + +{% block title %}{% if form.new_password1.errors or form.new_password2.errors %}{% translate "Error:" %} {% endif %}{{ block.super }}{% endblock %} +{% block extrastyle %}{{ block.super }}{% endblock %} +{% block breadcrumbs %} + +{% endblock %} + +{% block content %} + +{% if validlink %} + +

    {% translate "Please enter your new password twice so we can verify you typed it in correctly." %}

    + +
    {% csrf_token %} +
    + +
    + {{ form.new_password1.errors }} +
    + + {{ form.new_password1 }} +
    +
    +
    + {{ form.new_password2.errors }} +
    + + {{ form.new_password2 }} +
    +
    +
    +
    + +
    +
    + +{% else %} + +

    {% translate "The password reset link was invalid, possibly because it has already been used. Please request a new password reset." %}

    + +{% endif %} + +{% endblock %} diff --git a/venv/lib/python3.11/site-packages/django/contrib/admin/templates/registration/password_reset_done.html b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/registration/password_reset_done.html new file mode 100644 index 0000000..8b1971a --- /dev/null +++ b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/registration/password_reset_done.html @@ -0,0 +1,17 @@ +{% extends "admin/base_site.html" %} +{% load i18n %} + +{% block breadcrumbs %} + +{% endblock %} + +{% block content %} + +

    {% translate 'We’ve emailed you instructions for setting your password, if an account exists with the email you entered. You should receive them shortly.' %}

    + +

    {% translate 'If you don’t receive an email, please make sure you’ve entered the address you registered with, and check your spam folder.' %}

    + +{% endblock %} diff --git a/venv/lib/python3.11/site-packages/django/contrib/admin/templates/registration/password_reset_email.html b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/registration/password_reset_email.html new file mode 100644 index 0000000..2a428c4 --- /dev/null +++ b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/registration/password_reset_email.html @@ -0,0 +1,14 @@ +{% load i18n %}{% autoescape off %} +{% blocktranslate %}You're receiving this email because you requested a password reset for your user account at {{ site_name }}.{% endblocktranslate %} + +{% translate "Please go to the following page and choose a new password:" %} +{% block reset_link %} +{{ protocol }}://{{ domain }}{% url 'password_reset_confirm' uidb64=uid token=token %} +{% endblock %} +{% translate 'In case you’ve forgotten, you are:' %} {{ user.get_username }} + +{% translate "Thanks for using our site!" %} + +{% blocktranslate %}The {{ site_name }} team{% endblocktranslate %} + +{% endautoescape %} diff --git a/venv/lib/python3.11/site-packages/django/contrib/admin/templates/registration/password_reset_form.html b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/registration/password_reset_form.html new file mode 100644 index 0000000..e12189a --- /dev/null +++ b/venv/lib/python3.11/site-packages/django/contrib/admin/templates/registration/password_reset_form.html @@ -0,0 +1,32 @@ +{% extends "admin/base_site.html" %} +{% load i18n static %} + +{% block title %}{% if form.email.errors %}{% translate "Error:" %} {% endif %}{{ block.super }}{% endblock %} +{% block extrastyle %}{{ block.super }}{% endblock %} +{% block breadcrumbs %} + +{% endblock %} + +{% block content %} + +

    {% translate 'Forgotten your password? Enter your email address below, and we’ll email instructions for setting a new one.' %}

    + +
    {% csrf_token %} +
    +
    + {{ form.email.errors }} +
    + + {{ form.email }} +
    +
    +
    +
    + +
    +
    + +{% endblock %} diff --git a/venv/lib/python3.11/site-packages/django/contrib/admin/templatetags/__init__.py b/venv/lib/python3.11/site-packages/django/contrib/admin/templatetags/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/venv/lib/python3.11/site-packages/django/contrib/admin/templatetags/__pycache__/__init__.cpython-311.pyc b/venv/lib/python3.11/site-packages/django/contrib/admin/templatetags/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000..52a5be2 Binary files /dev/null and b/venv/lib/python3.11/site-packages/django/contrib/admin/templatetags/__pycache__/__init__.cpython-311.pyc differ diff --git a/venv/lib/python3.11/site-packages/django/contrib/admin/templatetags/__pycache__/admin_list.cpython-311.pyc b/venv/lib/python3.11/site-packages/django/contrib/admin/templatetags/__pycache__/admin_list.cpython-311.pyc new file mode 100644 index 0000000..9d3eb0c Binary files /dev/null and b/venv/lib/python3.11/site-packages/django/contrib/admin/templatetags/__pycache__/admin_list.cpython-311.pyc differ diff --git a/venv/lib/python3.11/site-packages/django/contrib/admin/templatetags/__pycache__/admin_modify.cpython-311.pyc b/venv/lib/python3.11/site-packages/django/contrib/admin/templatetags/__pycache__/admin_modify.cpython-311.pyc new file mode 100644 index 0000000..57d5a5c Binary files /dev/null and b/venv/lib/python3.11/site-packages/django/contrib/admin/templatetags/__pycache__/admin_modify.cpython-311.pyc differ diff --git a/venv/lib/python3.11/site-packages/django/contrib/admin/templatetags/__pycache__/admin_urls.cpython-311.pyc b/venv/lib/python3.11/site-packages/django/contrib/admin/templatetags/__pycache__/admin_urls.cpython-311.pyc new file mode 100644 index 0000000..a7affd4 Binary files /dev/null and b/venv/lib/python3.11/site-packages/django/contrib/admin/templatetags/__pycache__/admin_urls.cpython-311.pyc differ diff --git a/venv/lib/python3.11/site-packages/django/contrib/admin/templatetags/__pycache__/base.cpython-311.pyc b/venv/lib/python3.11/site-packages/django/contrib/admin/templatetags/__pycache__/base.cpython-311.pyc new file mode 100644 index 0000000..f457158 Binary files /dev/null and b/venv/lib/python3.11/site-packages/django/contrib/admin/templatetags/__pycache__/base.cpython-311.pyc differ diff --git a/venv/lib/python3.11/site-packages/django/contrib/admin/templatetags/__pycache__/log.cpython-311.pyc b/venv/lib/python3.11/site-packages/django/contrib/admin/templatetags/__pycache__/log.cpython-311.pyc new file mode 100644 index 0000000..3f426aa Binary files /dev/null and b/venv/lib/python3.11/site-packages/django/contrib/admin/templatetags/__pycache__/log.cpython-311.pyc differ diff --git a/venv/lib/python3.11/site-packages/django/contrib/admin/templatetags/admin_list.py b/venv/lib/python3.11/site-packages/django/contrib/admin/templatetags/admin_list.py new file mode 100644 index 0000000..6615e98 --- /dev/null +++ b/venv/lib/python3.11/site-packages/django/contrib/admin/templatetags/admin_list.py @@ -0,0 +1,544 @@ +import datetime + +from django.contrib.admin.templatetags.admin_urls import add_preserved_filters +from django.contrib.admin.utils import ( + display_for_field, + display_for_value, + get_fields_from_path, + label_for_field, + lookup_field, +) +from django.contrib.admin.views.main import ( + ALL_VAR, + IS_FACETS_VAR, + IS_POPUP_VAR, + ORDER_VAR, + PAGE_VAR, + SEARCH_VAR, +) +from django.core.exceptions import ObjectDoesNotExist +from django.db import models +from django.db.models.constants import LOOKUP_SEP +from django.template import Library +from django.template.loader import get_template +from django.templatetags.static import static +from django.urls import NoReverseMatch +from django.utils import formats, timezone +from django.utils.html import format_html +from django.utils.safestring import mark_safe +from django.utils.text import capfirst +from django.utils.translation import gettext as _ + +from .base import InclusionAdminNode + +register = Library() + + +@register.simple_tag +def paginator_number(cl, i): + """ + Generate an individual page index link in a paginated list. + """ + if i == cl.paginator.ELLIPSIS: + return format_html("{} ", cl.paginator.ELLIPSIS) + elif i == cl.page_num: + return format_html('{} ', i) + else: + return format_html( + '{} ', + cl.get_query_string({PAGE_VAR: i}), + mark_safe(' class="end"' if i == cl.paginator.num_pages else ""), + i, + ) + + +def pagination(cl): + """ + Generate the series of links to the pages in a paginated list. + """ + pagination_required = (not cl.show_all or not cl.can_show_all) and cl.multi_page + page_range = ( + cl.paginator.get_elided_page_range(cl.page_num) if pagination_required else [] + ) + need_show_all_link = cl.can_show_all and not cl.show_all and cl.multi_page + return { + "cl": cl, + "pagination_required": pagination_required, + "show_all_url": need_show_all_link and cl.get_query_string({ALL_VAR: ""}), + "page_range": page_range, + "ALL_VAR": ALL_VAR, + "1": 1, + } + + +@register.tag(name="pagination") +def pagination_tag(parser, token): + return InclusionAdminNode( + parser, + token, + func=pagination, + template_name="pagination.html", + takes_context=False, + ) + + +def result_headers(cl): + """ + Generate the list column headers. + """ + ordering_field_columns = cl.get_ordering_field_columns() + for i, field_name in enumerate(cl.list_display): + text, attr = label_for_field( + field_name, cl.model, model_admin=cl.model_admin, return_attr=True + ) + is_field_sortable = cl.sortable_by is None or field_name in cl.sortable_by + if attr: + field_name = _coerce_field_name(field_name, i) + # Potentially not sortable + + # if the field is the action checkbox: no sorting and special class + if field_name == "action_checkbox": + aria_label = _("Select all objects on this page for an action") + yield { + "text": mark_safe( + f'' + ), + "class_attrib": mark_safe(' class="action-checkbox-column"'), + "sortable": False, + } + continue + + admin_order_field = getattr(attr, "admin_order_field", None) + # Set ordering for attr that is a property, if defined. + if isinstance(attr, property) and hasattr(attr, "fget"): + admin_order_field = getattr(attr.fget, "admin_order_field", None) + if not admin_order_field and LOOKUP_SEP not in field_name: + is_field_sortable = False + + if not is_field_sortable: + # Not sortable + yield { + "text": text, + "class_attrib": format_html(' class="column-{}"', field_name), + "sortable": False, + } + continue + + # OK, it is sortable if we got this far + th_classes = ["sortable", "column-{}".format(field_name)] + order_type = "" + new_order_type = "asc" + sort_priority = 0 + # Is it currently being sorted on? + is_sorted = i in ordering_field_columns + if is_sorted: + order_type = ordering_field_columns.get(i).lower() + sort_priority = list(ordering_field_columns).index(i) + 1 + th_classes.append("sorted %sending" % order_type) + new_order_type = {"asc": "desc", "desc": "asc"}[order_type] + + # build new ordering param + o_list_primary = [] # URL for making this field the primary sort + o_list_remove = [] # URL for removing this field from sort + o_list_toggle = [] # URL for toggling order type for this field + + def make_qs_param(t, n): + return ("-" if t == "desc" else "") + str(n) + + for j, ot in ordering_field_columns.items(): + if j == i: # Same column + param = make_qs_param(new_order_type, j) + # We want clicking on this header to bring the ordering to the + # front + o_list_primary.insert(0, param) + o_list_toggle.append(param) + # o_list_remove - omit + else: + param = make_qs_param(ot, j) + o_list_primary.append(param) + o_list_toggle.append(param) + o_list_remove.append(param) + + if i not in ordering_field_columns: + o_list_primary.insert(0, make_qs_param(new_order_type, i)) + + yield { + "text": text, + "sortable": True, + "sorted": is_sorted, + "ascending": order_type == "asc", + "sort_priority": sort_priority, + "url_primary": cl.get_query_string({ORDER_VAR: ".".join(o_list_primary)}), + "url_remove": cl.get_query_string({ORDER_VAR: ".".join(o_list_remove)}), + "url_toggle": cl.get_query_string({ORDER_VAR: ".".join(o_list_toggle)}), + "class_attrib": ( + format_html(' class="{}"', " ".join(th_classes)) if th_classes else "" + ), + } + + +def _boolean_icon(field_val): + icon_url = static( + "admin/img/icon-%s.svg" % {True: "yes", False: "no", None: "unknown"}[field_val] + ) + return format_html('{}', icon_url, field_val) + + +def _coerce_field_name(field_name, field_index): + """ + Coerce a field_name (which may be a callable) to a string. + """ + if callable(field_name): + if field_name.__name__ == "": + return "lambda" + str(field_index) + else: + return field_name.__name__ + return field_name + + +def items_for_result(cl, result, form): + """ + Generate the actual list of data. + """ + + def link_in_col(is_first, field_name, cl): + if cl.list_display_links is None: + return False + if is_first and not cl.list_display_links: + return True + return field_name in cl.list_display_links + + first = True + pk = cl.lookup_opts.pk.attname + for field_index, field_name in enumerate(cl.list_display): + empty_value_display = cl.model_admin.get_empty_value_display() + row_classes = ["field-%s" % _coerce_field_name(field_name, field_index)] + link_to_changelist = link_in_col(first, field_name, cl) + try: + f, attr, value = lookup_field(field_name, result, cl.model_admin) + except ObjectDoesNotExist: + result_repr = empty_value_display + else: + empty_value_display = getattr( + attr, "empty_value_display", empty_value_display + ) + if isinstance(value, str) and value.strip() == "": + value = "" + if f is None or f.auto_created: + if field_name == "action_checkbox": + row_classes = ["action-checkbox"] + boolean = getattr(attr, "boolean", False) + # Set boolean for attr that is a property, if defined. + if isinstance(attr, property) and hasattr(attr, "fget"): + boolean = getattr(attr.fget, "boolean", False) + result_repr = display_for_value(value, empty_value_display, boolean) + if isinstance(value, (datetime.date, datetime.time)): + row_classes.append("nowrap") + else: + if isinstance(f.remote_field, models.ManyToOneRel): + field_val = getattr(result, f.name) + if field_val is None: + result_repr = empty_value_display + else: + result_repr = field_val + else: + result_repr = display_for_field( + value, + f, + empty_value_display, + avoid_link=link_to_changelist, + ) + if isinstance( + f, (models.DateField, models.TimeField, models.ForeignKey) + ): + row_classes.append("nowrap") + row_class = mark_safe(' class="%s"' % " ".join(row_classes)) + # If list_display_links not defined, add the link tag to the first field + if link_to_changelist: + table_tag = "th" if first else "td" + first = False + + # Display link to the result's change_view if the url exists, else + # display just the result's representation. + try: + url = cl.url_for_result(result) + except NoReverseMatch: + link_or_text = result_repr + else: + url = add_preserved_filters( + {"preserved_filters": cl.preserved_filters, "opts": cl.opts}, url + ) + # Convert the pk to something that can be used in JavaScript. + # Problem cases are non-ASCII strings. + if cl.to_field: + attr = str(cl.to_field) + else: + attr = pk + value = result.serializable_value(attr) + link_or_text = format_html( + '{}', + url, + ( + format_html(' data-popup-opener="{}"', value) + if cl.is_popup + else "" + ), + result_repr, + ) + + yield format_html( + "<{}{}>{}", table_tag, row_class, link_or_text, table_tag + ) + else: + # By default the fields come from ModelAdmin.list_editable, but if we pull + # the fields out of the form instead of list_editable custom admins + # can provide fields on a per request basis + if ( + form + and field_name in form.fields + and not ( + field_name == cl.model._meta.pk.name + and form[cl.model._meta.pk.name].is_hidden + ) + ): + bf = form[field_name] + result_repr = mark_safe(str(bf.errors) + str(bf)) + yield format_html("{}", row_class, result_repr) + if form and not form[cl.model._meta.pk.name].is_hidden: + yield format_html("{}", form[cl.model._meta.pk.name]) + + +class ResultList(list): + """ + Wrapper class used to return items in a list_editable changelist, annotated + with the form object for error reporting purposes. Needed to maintain + backwards compatibility with existing admin templates. + """ + + def __init__(self, form, *items): + self.form = form + super().__init__(*items) + + +def results(cl): + if cl.formset: + for res, form in zip(cl.result_list, cl.formset.forms): + yield ResultList(form, items_for_result(cl, res, form)) + else: + for res in cl.result_list: + yield ResultList(None, items_for_result(cl, res, None)) + + +def result_hidden_fields(cl): + if cl.formset: + for res, form in zip(cl.result_list, cl.formset.forms): + if form[cl.model._meta.pk.name].is_hidden: + yield mark_safe(form[cl.model._meta.pk.name]) + + +def result_list(cl): + """ + Display the headers and data list together. + """ + headers = list(result_headers(cl)) + num_sorted_fields = 0 + for h in headers: + if h["sortable"] and h["sorted"]: + num_sorted_fields += 1 + return { + "cl": cl, + "result_hidden_fields": list(result_hidden_fields(cl)), + "result_headers": headers, + "num_sorted_fields": num_sorted_fields, + "results": list(results(cl)), + } + + +@register.tag(name="result_list") +def result_list_tag(parser, token): + return InclusionAdminNode( + parser, + token, + func=result_list, + template_name="change_list_results.html", + takes_context=False, + ) + + +def date_hierarchy(cl): + """ + Display the date hierarchy for date drill-down functionality. + """ + if cl.date_hierarchy: + field_name = cl.date_hierarchy + field = get_fields_from_path(cl.model, field_name)[-1] + if isinstance(field, models.DateTimeField): + dates_or_datetimes = "datetimes" + else: + dates_or_datetimes = "dates" + year_field = "%s__year" % field_name + month_field = "%s__month" % field_name + day_field = "%s__day" % field_name + field_generic = "%s__" % field_name + year_lookup = cl.params.get(year_field) + month_lookup = cl.params.get(month_field) + day_lookup = cl.params.get(day_field) + + def link(filters): + return cl.get_query_string(filters, [field_generic]) + + if not (year_lookup or month_lookup or day_lookup): + # select appropriate start level + date_range = cl.queryset.aggregate( + first=models.Min(field_name), last=models.Max(field_name) + ) + if date_range["first"] and date_range["last"]: + if dates_or_datetimes == "datetimes": + date_range = { + k: timezone.localtime(v) if timezone.is_aware(v) else v + for k, v in date_range.items() + } + if date_range["first"].year == date_range["last"].year: + year_lookup = date_range["first"].year + if date_range["first"].month == date_range["last"].month: + month_lookup = date_range["first"].month + + if year_lookup and month_lookup and day_lookup: + day = datetime.date(int(year_lookup), int(month_lookup), int(day_lookup)) + return { + "show": True, + "back": { + "link": link({year_field: year_lookup, month_field: month_lookup}), + "title": capfirst(formats.date_format(day, "YEAR_MONTH_FORMAT")), + }, + "choices": [ + {"title": capfirst(formats.date_format(day, "MONTH_DAY_FORMAT"))} + ], + } + elif year_lookup and month_lookup: + days = getattr(cl.queryset, dates_or_datetimes)(field_name, "day") + return { + "show": True, + "back": { + "link": link({year_field: year_lookup}), + "title": str(year_lookup), + }, + "choices": [ + { + "link": link( + { + year_field: year_lookup, + month_field: month_lookup, + day_field: day.day, + } + ), + "title": capfirst(formats.date_format(day, "MONTH_DAY_FORMAT")), + } + for day in days + ], + } + elif year_lookup: + months = getattr(cl.queryset, dates_or_datetimes)(field_name, "month") + return { + "show": True, + "back": {"link": link({}), "title": _("All dates")}, + "choices": [ + { + "link": link( + {year_field: year_lookup, month_field: month.month} + ), + "title": capfirst( + formats.date_format(month, "YEAR_MONTH_FORMAT") + ), + } + for month in months + ], + } + else: + years = getattr(cl.queryset, dates_or_datetimes)(field_name, "year") + return { + "show": True, + "back": None, + "choices": [ + { + "link": link({year_field: str(year.year)}), + "title": str(year.year), + } + for year in years + ], + } + + +@register.tag(name="date_hierarchy") +def date_hierarchy_tag(parser, token): + return InclusionAdminNode( + parser, + token, + func=date_hierarchy, + template_name="date_hierarchy.html", + takes_context=False, + ) + + +def search_form(cl): + """ + Display a search form for searching the list. + """ + return { + "cl": cl, + "show_result_count": cl.result_count != cl.full_result_count, + "search_var": SEARCH_VAR, + "is_popup_var": IS_POPUP_VAR, + "is_facets_var": IS_FACETS_VAR, + } + + +@register.tag(name="search_form") +def search_form_tag(parser, token): + return InclusionAdminNode( + parser, + token, + func=search_form, + template_name="search_form.html", + takes_context=False, + ) + + +@register.simple_tag +def admin_list_filter(cl, spec): + tpl = get_template(spec.template) + return tpl.render( + { + "title": spec.title, + "choices": list(spec.choices(cl)), + "spec": spec, + } + ) + + +def admin_actions(context): + """ + Track the number of times the action field has been rendered on the page, + so we know which value to use. + """ + context["action_index"] = context.get("action_index", -1) + 1 + return context + + +@register.tag(name="admin_actions") +def admin_actions_tag(parser, token): + return InclusionAdminNode( + parser, token, func=admin_actions, template_name="actions.html" + ) + + +@register.tag(name="change_list_object_tools") +def change_list_object_tools_tag(parser, token): + """Display the row of change list object tools.""" + return InclusionAdminNode( + parser, + token, + func=lambda context: context, + template_name="change_list_object_tools.html", + ) diff --git a/venv/lib/python3.11/site-packages/django/contrib/admin/templatetags/admin_modify.py b/venv/lib/python3.11/site-packages/django/contrib/admin/templatetags/admin_modify.py new file mode 100644 index 0000000..0e3046a --- /dev/null +++ b/venv/lib/python3.11/site-packages/django/contrib/admin/templatetags/admin_modify.py @@ -0,0 +1,150 @@ +import json + +from django import template +from django.template.context import Context + +from .base import InclusionAdminNode + +register = template.Library() + + +def prepopulated_fields_js(context): + """ + Create a list of prepopulated_fields that should render JavaScript for + the prepopulated fields for both the admin form and inlines. + """ + prepopulated_fields = [] + if "adminform" in context: + prepopulated_fields.extend(context["adminform"].prepopulated_fields) + if "inline_admin_formsets" in context: + for inline_admin_formset in context["inline_admin_formsets"]: + for inline_admin_form in inline_admin_formset: + if inline_admin_form.original is None: + prepopulated_fields.extend(inline_admin_form.prepopulated_fields) + + prepopulated_fields_json = [] + for field in prepopulated_fields: + prepopulated_fields_json.append( + { + "id": "#%s" % field["field"].auto_id, + "name": field["field"].name, + "dependency_ids": [ + "#%s" % dependency.auto_id for dependency in field["dependencies"] + ], + "dependency_list": [ + dependency.name for dependency in field["dependencies"] + ], + "maxLength": field["field"].field.max_length or 50, + "allowUnicode": getattr(field["field"].field, "allow_unicode", False), + } + ) + + context.update( + { + "prepopulated_fields": prepopulated_fields, + "prepopulated_fields_json": json.dumps(prepopulated_fields_json), + } + ) + return context + + +@register.tag(name="prepopulated_fields_js") +def prepopulated_fields_js_tag(parser, token): + return InclusionAdminNode( + parser, + token, + func=prepopulated_fields_js, + template_name="prepopulated_fields_js.html", + ) + + +def submit_row(context): + """ + Display the row of buttons for delete and save. + """ + add = context["add"] + change = context["change"] + is_popup = context["is_popup"] + save_as = context["save_as"] + show_save = context.get("show_save", True) + show_save_and_add_another = context.get("show_save_and_add_another", True) + show_save_and_continue = context.get("show_save_and_continue", True) + has_add_permission = context["has_add_permission"] + has_change_permission = context["has_change_permission"] + has_view_permission = context["has_view_permission"] + has_editable_inline_admin_formsets = context["has_editable_inline_admin_formsets"] + can_save = ( + (has_change_permission and change) + or (has_add_permission and add) + or has_editable_inline_admin_formsets + ) + can_save_and_add_another = ( + has_add_permission + and not is_popup + and (not save_as or add) + and can_save + and show_save_and_add_another + ) + can_save_and_continue = ( + not is_popup and can_save and has_view_permission and show_save_and_continue + ) + can_change = has_change_permission or has_editable_inline_admin_formsets + ctx = Context(context) + ctx.update( + { + "can_change": can_change, + "show_delete_link": ( + not is_popup + and context["has_delete_permission"] + and change + and context.get("show_delete", True) + ), + "show_save_as_new": not is_popup + and has_add_permission + and change + and save_as, + "show_save_and_add_another": can_save_and_add_another, + "show_save_and_continue": can_save_and_continue, + "show_save": show_save and can_save, + "show_close": not (show_save and can_save), + } + ) + return ctx + + +@register.tag(name="submit_row") +def submit_row_tag(parser, token): + return InclusionAdminNode( + parser, token, func=submit_row, template_name="submit_line.html" + ) + + +@register.tag(name="change_form_object_tools") +def change_form_object_tools_tag(parser, token): + """Display the row of change form object tools.""" + return InclusionAdminNode( + parser, + token, + func=lambda context: context, + template_name="change_form_object_tools.html", + ) + + +@register.filter +def cell_count(inline_admin_form): + """Return the number of cells used in a tabular inline.""" + count = 1 # Hidden cell with hidden 'id' field + for fieldset in inline_admin_form: + # Count all visible fields. + for line in fieldset: + for field in line: + try: + is_hidden = field.field.is_hidden + except AttributeError: + is_hidden = field.field["is_hidden"] + if not is_hidden: + count += 1 + if inline_admin_form.formset.can_delete: + # Delete checkbox + count += 1 + return count diff --git a/venv/lib/python3.11/site-packages/django/contrib/admin/templatetags/admin_urls.py b/venv/lib/python3.11/site-packages/django/contrib/admin/templatetags/admin_urls.py new file mode 100644 index 0000000..176e7a4 --- /dev/null +++ b/venv/lib/python3.11/site-packages/django/contrib/admin/templatetags/admin_urls.py @@ -0,0 +1,70 @@ +from urllib.parse import parse_qsl, unquote, urlsplit, urlunsplit + +from django import template +from django.contrib.admin.utils import quote +from django.urls import Resolver404, get_script_prefix, resolve +from django.utils.http import urlencode + +register = template.Library() + + +@register.filter +def admin_urlname(value, arg): + return "admin:%s_%s_%s" % (value.app_label, value.model_name, arg) + + +@register.filter +def admin_urlquote(value): + return quote(value) + + +@register.simple_tag(takes_context=True) +def add_preserved_filters(context, url, popup=False, to_field=None): + opts = context.get("opts") + preserved_filters = context.get("preserved_filters") + preserved_qsl = context.get("preserved_qsl") + + parsed_url = list(urlsplit(url)) + parsed_qs = dict(parse_qsl(parsed_url[3])) + merged_qs = {} + + if preserved_qsl: + merged_qs.update(preserved_qsl) + + if opts and preserved_filters: + preserved_filters = dict(parse_qsl(preserved_filters)) + + match_url = "/%s" % unquote(url).partition(get_script_prefix())[2] + try: + match = resolve(match_url) + except Resolver404: + pass + else: + current_url = "%s:%s" % (match.app_name, match.url_name) + changelist_url = "admin:%s_%s_changelist" % ( + opts.app_label, + opts.model_name, + ) + if ( + changelist_url == current_url + and "_changelist_filters" in preserved_filters + ): + preserved_filters = dict( + parse_qsl(preserved_filters["_changelist_filters"]) + ) + + merged_qs.update(preserved_filters) + + if popup: + from django.contrib.admin.options import IS_POPUP_VAR + + merged_qs[IS_POPUP_VAR] = 1 + if to_field: + from django.contrib.admin.options import TO_FIELD_VAR + + merged_qs[TO_FIELD_VAR] = to_field + + merged_qs.update(parsed_qs) + + parsed_url[3] = urlencode(merged_qs) + return urlunsplit(parsed_url) diff --git a/venv/lib/python3.11/site-packages/django/contrib/admin/templatetags/base.py b/venv/lib/python3.11/site-packages/django/contrib/admin/templatetags/base.py new file mode 100644 index 0000000..9551c0e --- /dev/null +++ b/venv/lib/python3.11/site-packages/django/contrib/admin/templatetags/base.py @@ -0,0 +1,45 @@ +from inspect import getfullargspec + +from django.template.library import InclusionNode, parse_bits + + +class InclusionAdminNode(InclusionNode): + """ + Template tag that allows its template to be overridden per model, per app, + or globally. + """ + + def __init__(self, parser, token, func, template_name, takes_context=True): + self.template_name = template_name + params, varargs, varkw, defaults, kwonly, kwonly_defaults, _ = getfullargspec( + func + ) + bits = token.split_contents() + args, kwargs = parse_bits( + parser, + bits[1:], + params, + varargs, + varkw, + defaults, + kwonly, + kwonly_defaults, + takes_context, + bits[0], + ) + super().__init__(func, takes_context, args, kwargs, filename=None) + + def render(self, context): + opts = context["opts"] + app_label = opts.app_label.lower() + object_name = opts.model_name + # Load template for this render call. (Setting self.filename isn't + # thread-safe.) + context.render_context[self] = context.template.engine.select_template( + [ + "admin/%s/%s/%s" % (app_label, object_name, self.template_name), + "admin/%s/%s" % (app_label, self.template_name), + "admin/%s" % self.template_name, + ] + ) + return super().render(context) diff --git a/venv/lib/python3.11/site-packages/django/contrib/admin/templatetags/log.py b/venv/lib/python3.11/site-packages/django/contrib/admin/templatetags/log.py new file mode 100644 index 0000000..55b2c46 --- /dev/null +++ b/venv/lib/python3.11/site-packages/django/contrib/admin/templatetags/log.py @@ -0,0 +1,67 @@ +from django import template + +register = template.Library() + + +class AdminLogNode(template.Node): + def __init__(self, limit, varname, user): + self.limit = limit + self.varname = varname + self.user = user + + def __repr__(self): + return "" + + def render(self, context): + entries = context["log_entries"] + if self.user is not None: + user_id = self.user + if not user_id.isdigit(): + user_id = context[self.user].pk + entries = entries.filter(user__pk=user_id) + context[self.varname] = entries[: int(self.limit)] + return "" + + +@register.tag +def get_admin_log(parser, token): + """ + Populate a template variable with the admin log for the given criteria. + + Usage:: + + {% get_admin_log [limit] as [varname] for_user [context_var_with_user_obj] %} + + Examples:: + + {% get_admin_log 10 as admin_log for_user 23 %} + {% get_admin_log 10 as admin_log for_user user %} + {% get_admin_log 10 as admin_log %} + + Note that ``context_var_containing_user_obj`` can be a hard-coded integer + (user ID) or the name of a template context variable containing the user + object whose ID you want. + """ + tokens = token.contents.split() + if len(tokens) < 4: + raise template.TemplateSyntaxError( + "'get_admin_log' statements require two arguments" + ) + if not tokens[1].isdigit(): + raise template.TemplateSyntaxError( + "First argument to 'get_admin_log' must be an integer" + ) + if tokens[2] != "as": + raise template.TemplateSyntaxError( + "Second argument to 'get_admin_log' must be 'as'" + ) + if len(tokens) > 4: + if tokens[4] != "for_user": + raise template.TemplateSyntaxError( + "Fourth argument to 'get_admin_log' must be 'for_user'" + ) + return AdminLogNode( + limit=tokens[1], + varname=tokens[3], + user=(tokens[5] if len(tokens) > 5 else None), + ) diff --git a/venv/lib/python3.11/site-packages/django/contrib/admin/tests.py b/venv/lib/python3.11/site-packages/django/contrib/admin/tests.py new file mode 100644 index 0000000..636a6ff --- /dev/null +++ b/venv/lib/python3.11/site-packages/django/contrib/admin/tests.py @@ -0,0 +1,233 @@ +from contextlib import contextmanager + +from django.contrib.staticfiles.testing import StaticLiveServerTestCase +from django.test import modify_settings +from django.test.selenium import SeleniumTestCase +from django.utils.deprecation import MiddlewareMixin +from django.utils.translation import gettext as _ + +# Make unittest ignore frames in this module when reporting failures. +__unittest = True + + +class CSPMiddleware(MiddlewareMixin): + """The admin's JavaScript should be compatible with CSP.""" + + def process_response(self, request, response): + response.headers["Content-Security-Policy"] = "default-src 'self'" + return response + + +@modify_settings(MIDDLEWARE={"append": "django.contrib.admin.tests.CSPMiddleware"}) +class AdminSeleniumTestCase(SeleniumTestCase, StaticLiveServerTestCase): + available_apps = [ + "django.contrib.admin", + "django.contrib.auth", + "django.contrib.contenttypes", + "django.contrib.sessions", + "django.contrib.sites", + ] + + def wait_until(self, callback, timeout=10): + """ + Block the execution of the tests until the specified callback returns a + value that is not falsy. This method can be called, for example, after + clicking a link or submitting a form. See the other public methods that + call this function for more details. + """ + from selenium.webdriver.support.wait import WebDriverWait + + WebDriverWait(self.selenium, timeout).until(callback) + + def wait_for_and_switch_to_popup(self, num_windows=2, timeout=10): + """ + Block until `num_windows` are present and are ready (usually 2, but can + be overridden in the case of pop-ups opening other pop-ups). Switch the + current window to the new pop-up. + """ + self.wait_until(lambda d: len(d.window_handles) == num_windows, timeout) + self.selenium.switch_to.window(self.selenium.window_handles[-1]) + self.wait_page_ready() + + def wait_for(self, css_selector, timeout=10): + """ + Block until a CSS selector is found on the page. + """ + from selenium.webdriver.common.by import By + from selenium.webdriver.support import expected_conditions as ec + + self.wait_until( + ec.presence_of_element_located((By.CSS_SELECTOR, css_selector)), timeout + ) + + def wait_for_text(self, css_selector, text, timeout=10): + """ + Block until the text is found in the CSS selector. + """ + from selenium.webdriver.common.by import By + from selenium.webdriver.support import expected_conditions as ec + + self.wait_until( + ec.text_to_be_present_in_element((By.CSS_SELECTOR, css_selector), text), + timeout, + ) + + def wait_for_value(self, css_selector, text, timeout=10): + """ + Block until the value is found in the CSS selector. + """ + from selenium.webdriver.common.by import By + from selenium.webdriver.support import expected_conditions as ec + + self.wait_until( + ec.text_to_be_present_in_element_value( + (By.CSS_SELECTOR, css_selector), text + ), + timeout, + ) + + def wait_until_visible(self, css_selector, timeout=10): + """ + Block until the element described by the CSS selector is visible. + """ + from selenium.webdriver.common.by import By + from selenium.webdriver.support import expected_conditions as ec + + self.wait_until( + ec.visibility_of_element_located((By.CSS_SELECTOR, css_selector)), timeout + ) + + def wait_until_invisible(self, css_selector, timeout=10): + """ + Block until the element described by the CSS selector is invisible. + """ + from selenium.webdriver.common.by import By + from selenium.webdriver.support import expected_conditions as ec + + self.wait_until( + ec.invisibility_of_element_located((By.CSS_SELECTOR, css_selector)), timeout + ) + + def wait_page_ready(self, timeout=10): + """ + Block until the page is ready. + """ + self.wait_until( + lambda driver: driver.execute_script("return document.readyState;") + == "complete", + timeout, + ) + + @contextmanager + def wait_page_loaded(self, timeout=10): + """ + Block until a new page has loaded and is ready. + """ + from selenium.webdriver.common.by import By + from selenium.webdriver.support import expected_conditions as ec + + old_page = self.selenium.find_element(By.TAG_NAME, "html") + yield + # Wait for the next page to be loaded + self.wait_until(ec.staleness_of(old_page), timeout=timeout) + self.wait_page_ready(timeout=timeout) + + def admin_login(self, username, password, login_url="/admin/"): + """ + Log in to the admin. + """ + from selenium.webdriver.common.by import By + + self.selenium.get("%s%s" % (self.live_server_url, login_url)) + username_input = self.selenium.find_element(By.NAME, "username") + username_input.send_keys(username) + password_input = self.selenium.find_element(By.NAME, "password") + password_input.send_keys(password) + login_text = _("Log in") + with self.wait_page_loaded(): + self.selenium.find_element( + By.XPATH, '//input[@value="%s"]' % login_text + ).click() + + def select_option(self, selector, value): + """ + Select the