Created
July 1, 2025 21:15
-
-
Save kluchrj/5e4d018c792cc6a4031a1db262704b0c to your computer and use it in GitHub Desktop.
Django Unfold - Constance Admin Page
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| from datetime import date | |
| from datetime import datetime | |
| from datetime import time | |
| from datetime import timedelta | |
| from decimal import Decimal | |
| from django.contrib import admin | |
| from django.forms import fields | |
| from unfold import widgets | |
| from constance import settings, forms as constance_forms | |
| from constance.admin import ConstanceAdmin, Config | |
| NUMERIC_WIDGET = widgets.UnfoldAdminTextInputWidget(attrs={'size': 10}) | |
| INTEGER_LIKE = (fields.IntegerField, {'widget': NUMERIC_WIDGET}) | |
| STRING_LIKE = ( | |
| fields.CharField, | |
| { | |
| 'widget': widgets.UnfoldAdminTextareaWidget(attrs={'rows': 3}), | |
| 'required': False, | |
| }, | |
| ) | |
| FIELDS = { | |
| bool: (fields.BooleanField, {'required': False, 'widget': widgets.UnfoldBooleanSwitchWidget}), | |
| int: INTEGER_LIKE, | |
| Decimal: (fields.DecimalField, {'widget': NUMERIC_WIDGET}), | |
| str: STRING_LIKE, | |
| datetime: (fields.SplitDateTimeField, {'widget': widgets.UnfoldAdminSplitDateTimeWidget}), | |
| timedelta: (fields.DurationField, {'widget': widgets.UnfoldAdminTextInputWidget}), | |
| date: (fields.DateField, {'widget': widgets.UnfoldAdminDateWidget}), | |
| time: (fields.TimeField, {'widget': widgets.UnfoldAdminTimeWidget}), | |
| float: (fields.FloatField, {'widget': NUMERIC_WIDGET}), | |
| } | |
| # Don't call parse_additional_fields again - constance calls it before us. | |
| FIELDS.update(settings.ADDITIONAL_FIELDS) | |
| # Monkey patch constance module to use our custom fields. | |
| constance_forms.FIELDS = FIELDS | |
| class UnfoldConstanceForm(constance_forms.ConstanceForm): | |
| pass | |
| if admin.site.is_registered(ConstanceAdmin): | |
| admin.site.unregister(ConstanceAdmin) | |
| if admin.site.is_registered(Config): | |
| admin.site.unregister([Config]) | |
| class CustomConstanceAdmin(ConstanceAdmin): | |
| change_list_template = 'unfold/constance/index.html' | |
| change_list_form = UnfoldConstanceForm | |
| admin.site.register([Config], CustomConstanceAdmin) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| {% extends 'unfold/layouts/skeleton.html' %} | |
| {% load unfold i18n admin_urls %} | |
| {% block title %}{% if subtitle %}{{ subtitle }} | {% endif %}{{ title }} | {{ site_title|default:_('Django site admin') }}{% endblock %} | |
| {% block branding %} | |
| {% include "unfold/helpers/site_branding.html" %} | |
| {% endblock %} | |
| {% block base %} | |
| <div id="page" class="flex min-h-screen"> | |
| {% if not is_popup and is_nav_sidebar_enabled %} | |
| {% block nav-sidebar %} | |
| {% include "admin/nav_sidebar.html" %} | |
| {% endblock %} | |
| {% endif %} | |
| <div id="main" class="bg-white flex flex-col grow min-w-0 dark:bg-base-900 {% element_classes 'main' %}"> | |
| {% block content_before %} | |
| {% include "unfold/helpers/header.html" %} | |
| {% endblock %} | |
| {% if not is_popup %} | |
| {% spaceless %} | |
| {% block breadcrumbs %}{% endblock %} | |
| {% endspaceless %} | |
| {% endif %} | |
| {% block messages %} | |
| <div class="{% if not cl.model_admin.list_fullwidth %}container{% endif %} mx-auto"> | |
| {% include "unfold/helpers/messages.html" %} | |
| </div> | |
| {% endblock messages %} | |
| {% block content %} | |
| <div id="content-main" class="constance"> | |
| <div class="module" id="changelist"> | |
| <form id="changelist-form" action="" method="post" enctype="multipart/form-data">{% csrf_token %} | |
| <div class="px-4 pb-4"> | |
| <div class="container mx-auto {% block coltype %}colM{% endblock %}"> | |
| {% if form.non_field_errors %} | |
| <ul class="errorlist"> | |
| {% for error in form.non_field_errors %} | |
| <li>{{ error }}</li> | |
| {% endfor %} | |
| </ul> | |
| {% endif %} | |
| {% if form.errors %} | |
| <ul class="errorlist"> | |
| {% endif %} | |
| {% for field in form.hidden_fields %} | |
| {% for error in field.errors %} | |
| <li>{{ error }}</li> | |
| {% endfor %} | |
| {{ field }} | |
| {% endfor %} | |
| {% if form.errors %} | |
| </ul> | |
| {% endif %} | |
| {% if fieldsets %} | |
| {% for fieldset in fieldsets %} | |
| <fieldset class="module relative {% if fieldset.classes %} {{ fieldset.classes }}{% endif %}" {% if stacked != 1 %}x-show="activeTab == 'general'"{% endif %}> | |
| {% if fieldset.title %} | |
| <h2 class="bg-base-100 font-semibold mb-6 px-4 py-3 rounded-default text-font-important-light text-sm 2xl:-mx-4 dark:bg-white/[.02] dark:text-font-important-dark {% if fieldset.is_collapsible %}cursor-pointer{% endif %}"> | |
| {{ fieldset.title }} | |
| </h2> | |
| {% endif %} | |
| {% if fieldset.description %} | |
| <div class="leading-relaxed mb-4 max-w-4xl text-sm"> | |
| {{ fieldset.description|safe }} | |
| </div> | |
| {% endif %} | |
| <div class="{% fieldset_rows_classes %}"> | |
| {% with config_values=fieldset.config_values %} | |
| {% include "unfold/constance/results_list.html" %} | |
| {% endwith %} | |
| </div> | |
| </fieldset> | |
| {% endfor %} | |
| {% else %} | |
| {% include "unfold/constance/results_list.html" %} | |
| {% endif %} | |
| </div> | |
| </div> | |
| {% include "unfold/constance/submit_line.html" with is_popup=False %} | |
| </form> | |
| </div> | |
| </div> | |
| {% endblock %} | |
| {% block sidebar %}{% endblock %} | |
| {% block footer %}{% endblock %} | |
| </div> | |
| </div> | |
| {% endblock base %} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| {% load unfold static i18n %} | |
| <div id="results" class="w-full"> | |
| <div class="shadow-xs aligned rounded-default"> | |
| <table class="w-full border-collapse text-sm" style="table-layout: fixed"> | |
| <thead class="bg-muted text-muted-foreground uppercase tracking-wider text-xs border-b dark:border-base-800 border-base-200"> | |
| <tr> | |
| <th class="px-4 py-3 font-semibold text-left">{% trans "Name" %}</th> | |
| <th class="px-4 py-3 font-semibold text-left">{% trans "Default" %}</th> | |
| <th class="px-4 py-3 font-semibold text-left">{% trans "Value" %}</th> | |
| <th class="px-4 py-3 font-semibold text-center whitespace-nowrap">{% trans "Is modified" %}</th> | |
| </tr> | |
| </thead> | |
| <tbody> | |
| {% for item in config_values %} | |
| <tr class="bg-base hover:bg-muted border-b dark:border-base-800 border-base-200 transition"> | |
| <!-- Name --> | |
| <td class="px-4 py-4 align-middle" style="width: 20rem"> | |
| <div class="flex flex-col gap-1"> | |
| <span id="{{ item.name|slugify }}" class="text-sm font-bold uppercase tracking-tight"> | |
| {{ item.name }} | |
| <a href="#{{ item.name|slugify }}" | |
| title="{% trans 'Link to this setting' %}" | |
| class="ml-1 text-muted-foreground hover:text-foreground">¶</a> | |
| </span> | |
| {% if item.help_text %} | |
| <p class="text-xs text-muted leading-snug">{{ item.help_text|linebreaksbr }}</p> | |
| {% endif %} | |
| </div> | |
| </td> | |
| <!-- Default --> | |
| <td class="px-4 py-4 text-muted whitespace-pre-wrap align-middle"> | |
| {{ item.default }} | |
| </td> | |
| <!-- Field --> | |
| <td class="px-4 py-4 align-middle"> | |
| {% if item.form_field.errors %} | |
| <div class="text-sm text-destructive text-red-600 dark:text-red-500 mb-1">{{ item.form_field.errors }}</div> | |
| {% endif %} | |
| <div class="mt-1"> | |
| {{ item.form_field }} | |
| </div> | |
| </td> | |
| <!-- Is Modified --> | |
| <td class="px-4 py-4 text-center align-middle whitespace-nowrap"> | |
| {% if item.modified %} | |
| <img src="{% static 'admin/img/icon-yes.'|add:icon_type %}" alt="✔" class="inline h-5 w-5" /> | |
| {% else %} | |
| <img src="{% static 'admin/img/icon-no.'|add:icon_type %}" alt="✖" class="inline h-5 w-5" /> | |
| {% endif %} | |
| </td> | |
| </tr> | |
| {% endfor %} | |
| </tbody> | |
| </table> | |
| </div> | |
| </div> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| {% load i18n %} | |
| <div id="submit-row" class="relative lg:sticky lg:bottom-0 z-40"> | |
| <div class="backdrop-blur-xs bg-white/80 rounded-b-default pb-4 px-4 dark:bg-base-900/80 lg:border-t lg:border-base-200 relative lg:scrollable-top lg:py-0 dark:border-base-800"> | |
| <div class="flex flex-col-reverse gap-3 items-center mx-auto lg:flex-row-reverse container lg:h-[64px]"> | |
| <button type="submit" | |
| class="bg-primary-600 block border border-transparent cursor-pointer font-medium px-3 py-2 rounded-default text-white w-full lg:w-auto"> | |
| {% trans 'Save' %} | |
| </button> | |
| </div> | |
| </div> | |
| </div> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment