Skip to content

django-unfold-2: 自定义组件

Unfold 配备了一套全面的预定义模板,旨在加速仪表盘开发。Unfold 组件最强大的特性之一,是它们能够被嵌套在单个模板文件内,从而实现近乎无限的布局组合。每个组件都可以访问一个 children变量,该变量包含了由其父组件所指定的内容。除了 children变量,组件还可以从父模板接收多个变量作为组件参数。这些参数可以通过与 Django 模板相同的方式传递,即使用 {% include with param1=value1 param2=value2 %}模板标签语法。这种灵活性使得组件结构既高度可定制又可复用,同时保持了模板的清晰与条理性。

本文描述了如何在django unfold自定义组件,并在页面中调用。参照Django Unfold 组件,页面效果如下所示。

django-unfold组件

自定义组件步骤

  1. 注册组件 在admin.py中注册组件。
python
from unfold.components import BaseComponent, register_component
from start.models import Driver, DriverStatus

@register_component
class DriverActiveComponent(BaseComponent):
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)

        context["children"] = render_to_string(
            # 组件模板路径
            "start/helpers/kpi_progress.html",
            # 组件context
            {
                "total": Driver.objects.filter(status=DriverStatus.ACTIVE).count(),
                "progress": "positive",
                "percentage": "2.8%",
            },
        )
        return context
  1. 组件模板 组件模板为django模板,用于渲染组件。在组件模板中可以使用组件context中的变量。
html
<!-- kpi_progress.html -->
{% load humanize %}

<div class="flex flex-row items-center gap-3">
    {{ total|intcomma }}
    <span class="flex flex-row gap-1 items-center font-normal text-sm tracking-tight {% if progress == "positive" %}text-green-700 dark:text-green-400{% elif progress == "negative" %}text-red-700 dark:text-red-400{% endif %}">
        {% if progress == "positive" %}
            <span class="material-symbols-outlined">arrow_circle_up</span>
        {% elif progress == "negative" %}
            <span class="material-symbols-outlined">arrow_circle_down</span>
        {% else %}
            <span class="material-symbols-outlined text-gray-500">remove_circle</span>
        {% endif %}
        <span class="font-medium">{{ percentage }}</span>
    </span>
</div>
  1. 组件调用
  • 直接调用。可以在网页模板中直接调用组件,放入block content中。
html
{% block content %}
<div class="grid gap-4 mb-4 md:grid-cols-2 lg:grid-cols-4 ">
    {% component "unfold/components/card.html" %}
        {% component "unfold/components/text.html" %}
            {% trans "Active drivers" %}
        {% endcomponent %}

        {% component "unfold/components/title.html" with component_class="DriverActiveComponent" %}{% endcomponent %}
    {% endcomponent %}

</div>
{% endblock %}
  • 间接调用。在admin.py的ModelAdmin中通过list_before_template调用组件。
python
class DriverAdminMixin(ModelAdmin):
    # ……
    list_before_template = "start/driver_list_before.html"

driver_list_before.html为组件调用代码。

html
{% load unfold i18n %}
 
<div class="grid gap-4 mb-4 md:grid-cols-2 lg:grid-cols-4 ">
    {% component "unfold/components/card.html" %}
        {% component "unfold/components/text.html" %}
            {% trans "Active drivers" %}
        {% endcomponent %}

        {% component "unfold/components/title.html" with component_class="DriverActiveComponent" %}{% endcomponent %}
    {% endcomponent %}
 </div>

Released under the Apache 2.0 License.