• About Us
  • Privacy Policy
  • Disclaimer
  • Contact Us
AimactGrow
  • Home
  • Technology
  • AI
  • SEO
  • Coding
  • Gaming
  • Cybersecurity
  • Digital marketing
No Result
View All Result
  • Home
  • Technology
  • AI
  • SEO
  • Coding
  • Gaming
  • Cybersecurity
  • Digital marketing
No Result
View All Result
AimactGrow
No Result
View All Result

Tips on how to Construct a Django-Unfold Admin Dashboard with Customized Fashions, Filters, Actions, and KPIs

Admin by Admin
May 15, 2026
Home AI
Share on FacebookShare on Twitter


(ROOT / "store" / "admin.py").write_text('''
from django.contrib import admin, messages
from django.contrib.auth.admin import (UserAdmin as DjangoUserAdmin,
                                      GroupAdmin as DjangoGroupAdmin)
from django.contrib.auth.fashions import Person, Group
from django.shortcuts import redirect
from django.utils.html import format_html
from django.utils.translation import gettext_lazy as _
from unfold.admin import ModelAdmin, TabularInline
from unfold.contrib.filters.admin import (
   ChoicesDropdownFilter, RangeNumericFilter, RangeDateFilter,
   MultipleChoicesDropdownFilter,
)
from unfold.decorators import show, motion
from .fashions import Class, Buyer, Product, Order, OrderItem
admin.web site.unregister(Person); admin.web site.unregister(Group)
@admin.register(Person)
class UserAdmin(DjangoUserAdmin, ModelAdmin):
   move
@admin.register(Group)
class GroupAdmin(DjangoGroupAdmin, ModelAdmin):
   move
@admin.register(Class)
class CategoryAdmin(ModelAdmin):
   list_display = ("identify", "father or mother", "show_active", "created_at")
   list_filter  = (("is_active", ChoicesDropdownFilter),)
   search_fields = ("identify", "slug")
   prepopulated_fields = {"slug": ("identify",)}
   list_filter_submit = True
   compressed_fields = True
   @show(description=_("Lively"), boolean=True)
   def show_active(self, obj): return obj.is_active
@admin.register(Buyer)
class CustomerAdmin(ModelAdmin):
   list_display = ("identify","e mail","show_tier","lifetime_value","joined")
   list_filter  = (
       ("tier",            MultipleChoicesDropdownFilter),
       ("lifetime_value",  RangeNumericFilter),
       ("joined",          RangeDateFilter),
   )
   search_fields = ("identify","e mail")
   list_filter_submit = True
   warn_unsaved_form  = True
   list_per_page = 25
   @show(description=_("Tier"), label={
       "bronze":"warning","silver":"information","gold":"success","platinum":"major"})
   def show_tier(self, obj):
       return obj.get_tier_display(), obj.tier
class OrderItemInline(TabularInline):
   mannequin = OrderItem
   further = 0
   fields = ("product", "amount", "unit_price", "place")
   ordering_field = "place"
   tab = True
@admin.register(Order)
class OrderAdmin(ModelAdmin):
   list_display = ("quantity","customer_link","show_status","whole","created_at")
   list_filter  = (
       ("standing",     ChoicesDropdownFilter),
       ("whole",      RangeNumericFilter),
       ("created_at", RangeDateFilter),
   )
   search_fields = ("quantity","customer__name","customer__email")
   readonly_fields = ("created_at",)
   autocomplete_fields = ("buyer",)
   inlines = [OrderItemInline]
   list_filter_submit = True
   fieldsets = (
       (_("Order"), {"lessons":["tab"], "fields":("quantity","buyer","standing","whole")}),
       (_("Notes"), {"lessons":["tab"], "fields":("notes","created_at")}),
   )
   actions_list        = ["mark_paid_bulk"]
   actions_row         = ["mark_paid_row"]
   actions_detail      = ["duplicate_order"]
   actions_submit_line = ["save_and_ship"]
   @show(description=_("Standing"), label={
       "pending":"warning","paid":"information","shipped":"major",
       "delivered":"success","cancelled":"hazard"})
   def show_status(self, obj):
       return obj.get_status_display(), obj.standing
   @show(description=_("Buyer"))
   def customer_link(self, obj):
       return format_html('{}',
                          obj.customer_id, obj.buyer.identify)
   @motion(description=_("Mark pending → PAID (all)"), icon="funds")
   def mark_paid_bulk(self, request, queryset=None):
       n = Order.objects.filter(standing="pending").replace(standing="paid")
       self.message_user(request, f"Marked {n} orders as paid.", degree=messages.SUCCESS)
   @motion(description=_("Mark paid"), icon="funds", url_path="mark-paid-row")
   def mark_paid_row(self, request, object_id):
       Order.objects.filter(pk=object_id).replace(standing="paid")
       self.message_user(request, "Order marked as paid.", degree=messages.SUCCESS)
       return redirect(request.META.get("HTTP_REFERER","/admin/"))
   @motion(description=_("Duplicate"), icon="content_copy", url_path="duplicate")
   def duplicate_order(self, request, object_id):
       o = Order.objects.get(pk=object_id)
       o.pk = None; o.quantity = o.quantity + "-COPY"; o.standing = "pending"; o.save()
       self.message_user(request, "Order duplicated.", degree=messages.SUCCESS)
       return redirect(f"/admin/store/order/{o.pk}/change/")
   @motion(description=_("Save & ship"))
   def save_and_ship(self, request, obj):
       obj.standing = "shipped"; obj.save()
       self.message_user(request, f"Order {obj.quantity} shipped.", degree=messages.SUCCESS)
@admin.register(Product)
class ProductAdmin(ModelAdmin):
   list_display = ("identify","sku","class","show_status",
                   "price_display","stock_badge","featured")
   list_editable = ("featured",)
   list_filter   = (
       ("standing",   ChoicesDropdownFilter),
       ("class", admin.RelatedFieldListFilter),
       ("worth",    RangeNumericFilter),
       ("featured", ChoicesDropdownFilter),
   )
   search_fields = ("identify","sku")
   autocomplete_fields = ("class",)
   list_filter_submit = True
   list_per_page = 20
   save_on_top = True
   fieldsets = (
       (_("Fundamentals"),  {"lessons":["tab"],
                       "fields":("identify","sku","class","standing","featured")}),
       (_("Pricing"), {"lessons":["tab"],
                       "fields":("worth","has_discount","discount_percent","inventory")}),
       (_("Content material"), {"lessons":["tab"], "fields":("description",)}),
   )
   conditional_fields = {"discount_percent": "has_discount == true"}
   @show(description=_("Standing"), label={
       "draft":"information","lively":"success","archived":"warning"})
   def show_status(self, obj):
       return obj.get_status_display(), obj.standing
   @show(description=_("Value"))
   def price_display(self, obj):
       if obj.has_discount and obj.discount_percent:
           return format_html(
               '${} '
               '${}', obj.worth, obj.final_price)
       return f"${obj.worth}"
   @show(description=_("Inventory"), ordering="inventory",
            label={"out":"hazard","low":"warning","okay":"success"})
   def stock_badge(self, obj):
       if obj.inventory == 0:                  return "Out of inventory", "out"
       if obj.inventory < 10:                  return f"Low ({obj.inventory})", "low"
       return f"{obj.inventory} in inventory", "okay"
''')
(ROOT / "templates" / "admin" / "index.html").write_text('''{% extends "admin/index.html" %}
{% load i18n %}
{% block content material %}
{% for ok in kpis %}

{{ ok.title }}

{{ ok.worth }}

{{ ok.footer }}

{% endfor %}

{% trans "High classes" %}

    {% for c in top_cats %}
  • {{ c.identify }}{{ c.n }}
  • {% endfor %}

{% trans "Orders by standing" %}

    {% for s in by_status %}
  • {{ s.standing }}{{ s.c }}
  • {% endfor %}
{{ block.tremendous }} {% endblock %} ''')
Tags: actionsadminBuildCustomDashboardDjangoUnfoldfiltersKPIsModels
Admin

Admin

Next Post
NAND contract costs surge over 600% since September 2025, DRAM up ~400%

NAND contract costs surge over 600% since September 2025, DRAM up ~400%

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Recommended.

BitLocker Restoration Danger After October 2025 Updates

BitLocker Restoration Danger After October 2025 Updates

November 5, 2025
Musk denies consciousness of Grok sexual underage photographs as California AG launches probe

Musk denies consciousness of Grok sexual underage photographs as California AG launches probe

January 14, 2026

Trending.

From Basement to Breakthroughs: Contained in the Studio Powering the Web’s Boldest Manufacturers

From Basement to Breakthroughs: Contained in the Studio Powering the Web’s Boldest Manufacturers

December 15, 2025
HunyuanCustom Brings Single-Picture Video Deepfakes, With Audio and Lip Sync

HunyuanCustom Brings Single-Picture Video Deepfakes, With Audio and Lip Sync

May 8, 2025
A SQL MERGE assertion performs actions primarily based on a RIGHT JOIN

Use jOOQ’s code generator to simply go table-valued parameters

April 26, 2025
AI & data-driven Starbucks – Deep Brew

AI & data-driven Starbucks – Deep Brew

May 18, 2026
A SQL MERGE assertion performs actions primarily based on a RIGHT JOIN

With jOOQ – Java, SQL and jOOQ.

May 25, 2025

AimactGrow

Welcome to AimactGrow, your ultimate source for all things technology! Our mission is to provide insightful, up-to-date content on the latest advancements in technology, coding, gaming, digital marketing, SEO, cybersecurity, and artificial intelligence (AI).

Categories

  • AI
  • Coding
  • Cybersecurity
  • Digital marketing
  • Gaming
  • SEO
  • Technology

Recent News

The 4 Finest Planners of 2027: Roterunner, Hobonichi, Material & Paper

The 4 Finest Planners of 2027: Roterunner, Hobonichi, Material & Paper

November 15, 2026
GTA VI isn’t out but – and the scams are already out in full forc

GTA VI isn’t out but – and the scams are already out in full forc

November 15, 2026
  • About Us
  • Privacy Policy
  • Disclaimer
  • Contact Us

© 2025 https://blog.aimactgrow.com/ - All Rights Reserved

No Result
View All Result
  • Home
  • Technology
  • AI
  • SEO
  • Coding
  • Gaming
  • Cybersecurity
  • Digital marketing

© 2025 https://blog.aimactgrow.com/ - All Rights Reserved