2025-01-27 14:58:23 +01:00
|
|
|
from django.contrib import admin
|
2025-01-27 15:14:58 +01:00
|
|
|
from django.utils.html import format_html
|
2025-03-07 14:58:51 +01:00
|
|
|
from adminsortable2.admin import SortableAdminMixin
|
2025-05-20 14:26:31 +02:00
|
|
|
from import_export.admin import ImportExportModelAdmin
|
|
|
|
from import_export import resources
|
|
|
|
from import_export.fields import Field
|
|
|
|
from import_export.widgets import ForeignKeyWidget
|
2025-03-07 14:58:51 +01:00
|
|
|
|
2025-01-28 08:53:00 +01:00
|
|
|
from .models import (
|
2025-01-28 13:55:43 +01:00
|
|
|
Category,
|
2025-01-28 08:53:00 +01:00
|
|
|
CloudProvider,
|
2025-05-20 11:26:52 +02:00
|
|
|
ComputePlan,
|
2025-01-28 08:53:00 +01:00
|
|
|
ConsultingPartner,
|
2025-01-28 13:55:43 +01:00
|
|
|
ExternalLink,
|
2025-02-28 14:13:51 +01:00
|
|
|
ExternalLinkOffering,
|
|
|
|
Lead,
|
2025-01-28 10:41:39 +01:00
|
|
|
Plan,
|
2025-02-28 14:13:51 +01:00
|
|
|
ReusableText,
|
2025-01-28 13:55:43 +01:00
|
|
|
Service,
|
|
|
|
ServiceOffering,
|
2025-03-06 11:35:55 +01:00
|
|
|
WebsiteFaq,
|
2025-01-28 08:53:00 +01:00
|
|
|
)
|
2025-01-27 15:23:50 +01:00
|
|
|
|
2025-03-07 14:50:36 +01:00
|
|
|
|
2025-03-07 15:37:22 +01:00
|
|
|
class PlanInline(admin.StackedInline):
|
2025-03-07 14:50:36 +01:00
|
|
|
model = Plan
|
|
|
|
extra = 1
|
|
|
|
fieldsets = (
|
|
|
|
(None, {"fields": ("name", "description", "pricing", "plan_description")}),
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
class ExternalLinkOfferingInline(admin.TabularInline):
|
|
|
|
model = ExternalLinkOffering
|
|
|
|
extra = 1
|
|
|
|
fields = ("description", "url", "order")
|
|
|
|
ordering = ("order", "description")
|
|
|
|
|
|
|
|
|
2025-03-07 15:37:22 +01:00
|
|
|
class OfferingInline(admin.StackedInline):
|
2025-03-07 14:50:36 +01:00
|
|
|
model = ServiceOffering
|
|
|
|
extra = 1
|
|
|
|
fieldsets = (
|
|
|
|
(
|
|
|
|
None,
|
|
|
|
{
|
|
|
|
"fields": (
|
|
|
|
"description",
|
|
|
|
"service",
|
|
|
|
"cloud_provider",
|
|
|
|
"offer_description",
|
|
|
|
)
|
|
|
|
},
|
|
|
|
),
|
|
|
|
)
|
2025-03-07 15:37:22 +01:00
|
|
|
show_change_link = True
|
2025-03-07 14:50:36 +01:00
|
|
|
|
2025-01-27 15:23:50 +01:00
|
|
|
|
2025-02-28 14:13:51 +01:00
|
|
|
@admin.register(ReusableText)
|
|
|
|
class ReusableTextAdmin(admin.ModelAdmin):
|
|
|
|
list_display = ("name",)
|
|
|
|
search_fields = ("name", "text")
|
|
|
|
ordering = ("name",)
|
|
|
|
|
|
|
|
|
2025-01-27 15:23:50 +01:00
|
|
|
@admin.register(Category)
|
|
|
|
class CategoryAdmin(admin.ModelAdmin):
|
|
|
|
list_display = ("name", "slug", "parent", "order")
|
|
|
|
list_filter = ("parent",)
|
|
|
|
search_fields = ("name", "description")
|
|
|
|
prepopulated_fields = {"slug": ("name",)}
|
|
|
|
ordering = ("order", "name")
|
2025-01-27 14:58:23 +01:00
|
|
|
|
|
|
|
|
2025-05-20 11:26:52 +02:00
|
|
|
class ComputePlansInline(SortableAdminMixin, admin.ModelAdmin):
|
|
|
|
model = ComputePlan
|
|
|
|
extra = 1
|
|
|
|
fieldsets = ((None, {"fields": ("name", "vcpus", "ram", "price_chf")}),)
|
|
|
|
|
|
|
|
|
2025-01-27 14:58:23 +01:00
|
|
|
@admin.register(CloudProvider)
|
2025-03-12 06:41:33 +01:00
|
|
|
class CloudProviderAdmin(SortableAdminMixin, admin.ModelAdmin):
|
|
|
|
list_display = (
|
|
|
|
"name",
|
|
|
|
"slug",
|
|
|
|
"logo_preview",
|
|
|
|
"disable_listing",
|
|
|
|
"is_featured",
|
|
|
|
"order",
|
|
|
|
)
|
2025-01-28 13:55:43 +01:00
|
|
|
search_fields = ("name", "description")
|
2025-01-27 15:54:37 +01:00
|
|
|
prepopulated_fields = {"slug": ("name",)}
|
2025-03-06 16:50:36 +01:00
|
|
|
inlines = [OfferingInline]
|
2025-03-12 06:41:33 +01:00
|
|
|
ordering = ("order",)
|
2025-01-27 14:58:23 +01:00
|
|
|
|
2025-01-27 15:14:58 +01:00
|
|
|
def logo_preview(self, obj):
|
|
|
|
if obj.logo:
|
|
|
|
return format_html(
|
|
|
|
'<img src="{}" style="max-height: 50px;"/>', obj.logo.url
|
|
|
|
)
|
|
|
|
return "No logo"
|
|
|
|
|
2025-01-28 13:55:43 +01:00
|
|
|
logo_preview.short_description = "Logo"
|
|
|
|
|
|
|
|
|
|
|
|
class ExternalLinkInline(admin.TabularInline):
|
|
|
|
model = ExternalLink
|
|
|
|
extra = 1
|
|
|
|
fields = ("description", "url", "order")
|
|
|
|
ordering = ("order", "description")
|
|
|
|
|
2025-01-27 14:58:23 +01:00
|
|
|
|
|
|
|
@admin.register(Service)
|
|
|
|
class ServiceAdmin(admin.ModelAdmin):
|
2025-03-17 09:18:54 +01:00
|
|
|
list_display = (
|
|
|
|
"name",
|
|
|
|
"logo_preview",
|
|
|
|
"category_list",
|
|
|
|
"is_featured",
|
|
|
|
"is_coming_soon",
|
|
|
|
"disable_listing",
|
|
|
|
)
|
2025-01-28 13:55:43 +01:00
|
|
|
list_filter = ("categories",)
|
2025-01-27 17:00:56 +01:00
|
|
|
search_fields = ("name", "description", "slug")
|
|
|
|
prepopulated_fields = {"slug": ("name",)}
|
2025-01-28 13:55:43 +01:00
|
|
|
filter_horizontal = ("categories",)
|
2025-03-06 16:50:36 +01:00
|
|
|
inlines = [ExternalLinkInline, OfferingInline]
|
2025-01-27 15:14:58 +01:00
|
|
|
|
|
|
|
def logo_preview(self, obj):
|
|
|
|
if obj.logo:
|
|
|
|
return format_html(
|
|
|
|
'<img src="{}" style="max-height: 50px;"/>', obj.logo.url
|
|
|
|
)
|
|
|
|
return "No logo"
|
2025-01-27 15:23:50 +01:00
|
|
|
|
2025-01-28 13:55:43 +01:00
|
|
|
logo_preview.short_description = "Logo"
|
|
|
|
|
2025-01-27 15:23:50 +01:00
|
|
|
def category_list(self, obj):
|
|
|
|
return ", ".join([cat.name for cat in obj.categories.all()])
|
|
|
|
|
2025-01-28 13:55:43 +01:00
|
|
|
category_list.short_description = "Categories"
|
|
|
|
|
2025-01-28 08:53:00 +01:00
|
|
|
def partner_list(self, obj):
|
|
|
|
return ", ".join([partner.name for partner in obj.consulting_partners.all()])
|
|
|
|
|
|
|
|
partner_list.short_description = "Consulting Partners"
|
2025-01-28 13:55:43 +01:00
|
|
|
|
|
|
|
|
|
|
|
@admin.register(ServiceOffering)
|
|
|
|
class ServiceOfferingAdmin(admin.ModelAdmin):
|
2025-02-28 14:25:35 +01:00
|
|
|
list_display = ("service", "cloud_provider")
|
2025-01-28 13:55:43 +01:00
|
|
|
list_filter = ("service", "cloud_provider")
|
|
|
|
search_fields = ("service__name", "cloud_provider__name", "description")
|
2025-02-28 14:13:51 +01:00
|
|
|
inlines = [ExternalLinkOfferingInline, PlanInline]
|
2025-01-28 10:41:39 +01:00
|
|
|
|
2025-01-28 08:53:00 +01:00
|
|
|
|
|
|
|
@admin.register(ConsultingPartner)
|
2025-03-14 14:57:34 +01:00
|
|
|
class ConsultingPartnerAdmin(SortableAdminMixin, admin.ModelAdmin):
|
|
|
|
list_display = (
|
|
|
|
"name",
|
|
|
|
"website",
|
|
|
|
"logo_preview",
|
|
|
|
"disable_listing",
|
|
|
|
"is_featured",
|
|
|
|
"order",
|
|
|
|
)
|
2025-01-28 08:53:00 +01:00
|
|
|
search_fields = ("name", "description")
|
|
|
|
prepopulated_fields = {"slug": ("name",)}
|
2025-01-28 13:55:43 +01:00
|
|
|
filter_horizontal = ("services", "cloud_providers")
|
2025-03-14 14:57:34 +01:00
|
|
|
ordering = ("order",)
|
2025-01-28 08:53:00 +01:00
|
|
|
|
|
|
|
def logo_preview(self, obj):
|
|
|
|
if obj.logo:
|
|
|
|
return format_html(
|
|
|
|
'<img src="{}" style="max-height: 50px;"/>', obj.logo.url
|
|
|
|
)
|
|
|
|
return "No logo"
|
2025-01-28 10:41:39 +01:00
|
|
|
|
2025-01-28 13:55:43 +01:00
|
|
|
logo_preview.short_description = "Logo"
|
2025-01-31 11:12:00 +01:00
|
|
|
|
|
|
|
|
|
|
|
@admin.register(Lead)
|
|
|
|
class LeadAdmin(admin.ModelAdmin):
|
|
|
|
list_display = ("name", "company", "created_at", "odoo_lead_id")
|
|
|
|
search_fields = ("name", "company")
|
2025-03-06 11:35:55 +01:00
|
|
|
|
|
|
|
|
|
|
|
@admin.register(WebsiteFaq)
|
2025-03-07 14:58:51 +01:00
|
|
|
class WebsiteFaqAdmin(SortableAdminMixin, admin.ModelAdmin):
|
2025-03-06 11:35:55 +01:00
|
|
|
list_display = ("question", "order")
|
|
|
|
search_fields = ("question", "answer")
|
|
|
|
ordering = ("order",)
|
2025-05-20 11:26:52 +02:00
|
|
|
|
|
|
|
|
2025-05-20 14:26:31 +02:00
|
|
|
class ComputePlanResource(resources.ModelResource):
|
|
|
|
cloud_provider = Field(
|
|
|
|
column_name="cloud_provider",
|
|
|
|
attribute="cloud_provider",
|
|
|
|
widget=ForeignKeyWidget(CloudProvider, "name"),
|
|
|
|
)
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
model = ComputePlan
|
|
|
|
skip_unchanged = True
|
|
|
|
report_skipped = False
|
|
|
|
import_id_fields = ["name"]
|
|
|
|
fields = (
|
|
|
|
"name",
|
|
|
|
"vcpus",
|
|
|
|
"ram",
|
|
|
|
"cpu_mem_ratio",
|
|
|
|
"price_chf",
|
|
|
|
"cloud_provider",
|
|
|
|
)
|
|
|
|
|
|
|
|
|
2025-05-20 11:26:52 +02:00
|
|
|
@admin.register(ComputePlan)
|
2025-05-20 14:26:31 +02:00
|
|
|
class ComputePlansAdmin(ImportExportModelAdmin):
|
|
|
|
resource_class = ComputePlanResource
|
2025-05-20 11:26:52 +02:00
|
|
|
list_display = ("name", "cloud_provider", "vcpus", "ram", "price_chf", "active")
|
2025-05-20 14:26:31 +02:00
|
|
|
search_fields = ("name", "cloud_provider__name") # Search by cloud_provider name
|
2025-05-20 11:26:52 +02:00
|
|
|
ordering = ("name",)
|