Coverage for src/products/admin.py: 88%
91 statements
« prev ^ index » next coverage.py v7.9.2, created at 2025-09-21 16:24 +0300
« prev ^ index » next coverage.py v7.9.2, created at 2025-09-21 16:24 +0300
1from django.utils.html import format_html
2from django.utils.translation import gettext_lazy as _
3from django.contrib import admin
4from django.contrib.contenttypes.admin import GenericTabularInline
6from src.products.models import (
7 Collection,
8 Color,
9 Metal,
10 Stone,
11 Size,
12 Inventory,
13)
14from src.products.models.product import Bracelet, Earring, Necklace, Pendant, Ring, Watch
15from src.products.models.review import Review
18@admin.register(Collection)
19class CollectionAdmin(admin.ModelAdmin):
20 pass
23@admin.register(Color)
24class ColorAdmin(admin.ModelAdmin):
25 pass
28@admin.register(Metal)
29class MetalAdmin(admin.ModelAdmin):
30 pass
33@admin.register(Stone)
34class StoneAdmin(admin.ModelAdmin):
35 pass
38@admin.register(Size)
39class SizeAdmin(admin.ModelAdmin):
40 pass
43@admin.register(Inventory)
44class InventoryAdmin(admin.ModelAdmin):
45 pass
48class StoneListFilter(admin.SimpleListFilter):
49 title = _('Stone')
50 parameter_name = 'stone'
52 def lookups(self, request, model_admin):
53 return [(s.id, s.name) for s in Stone.objects.all()]
55 def queryset(self, request, queryset):
56 return (
57 queryset.filter(stone__id=self.value())
58 if self.value()
59 else queryset
60 )
63class ColorListFilter(admin.SimpleListFilter):
64 title = _('Color')
65 parameter_name = 'color'
67 def lookups(self, request, model_admin):
68 return [(c.id, c.name) for c in Color.objects.all()]
70 def queryset(self, request, queryset):
71 return (
72 queryset.filter(color__id=self.value())
73 if self.value()
74 else queryset
75 )
78class InventoryInline(GenericTabularInline):
79 model = Inventory
80 ct_field = "content_type"
81 ct_fk_field = "object_id"
82 min_num = 1
83 max_num = 3
84 validate_min = True
87class BaseProductAdmin(admin.ModelAdmin):
88 list_display = (
89 'first_picture',
90 'second_picture',
91 'collection',
92 'created_at',
93 'pk'
94 )
96 list_filter = (StoneListFilter, ColorListFilter, 'collection', 'metal')
98 ordering = (
99 'created_at',
100 'collection',
101 'metal',
102 )
104 search_fields = (
105 'collection__name',
106 'metal__name',
107 'color__name',
108 'stone__name',
109 )
111 fieldsets = (
112 ('Images', {'fields': ('first_image', 'second_image')}),
113 (
114 'Material and Design',
115 {
116 'fields': (
117 'collection',
118 'metal',
119 'stone',
120 'color',
121 )
122 },
123 ),
124 )
126 def first_picture(self, obj):
127 return format_html(
128 '<img src="{}" width="100" height="100" style="object-fit: cover;" />',
129 obj.first_image,
130 )
132 def second_picture(self, obj):
133 return format_html(
134 '<img src="{}" width="100" height="100" style="object-fit: cover;" />',
135 obj.second_image,
136 )
140@admin.register(Earring)
141class EarringAdmin(BaseProductAdmin):
142 inlines = [InventoryInline]
145@admin.register(Necklace)
146class NecklaceAdmin(BaseProductAdmin):
147 inlines = [InventoryInline]
150@admin.register(Pendant)
151class PendantAdmin(BaseProductAdmin):
152 inlines = [InventoryInline]
155@admin.register(Bracelet)
156class BraceletAdmin(BaseProductAdmin):
157 inlines = [InventoryInline]
160@admin.register(Watch)
161class WatchAdmin(BaseProductAdmin):
162 inlines = [InventoryInline]
165@admin.register(Ring)
166class RingAdmin(BaseProductAdmin):
167 inlines = [InventoryInline]
170@admin.register(Review)
171class ReviewAdmin(admin.ModelAdmin):
172 list_display = [
173 '__str__',
174 'user',
175 'rating',
176 'approved',
177 'created_at',
178 'product_link',
179 ]
180 list_filter = [
181 'approved',
182 'rating',
183 'created_at',
184 ]
185 search_fields = [
186 'user__email',
187 'user__userprofile__first_name',
188 'user__userprofile__last_name',
189 'comment',
190 ]
191 list_editable = ['approved']
192 readonly_fields = [
193 'user',
194 'rating',
195 'comment',
196 'created_at',
197 'content_type',
198 'object_id',
199 'product',
200 ]
201 ordering = ['-created_at']
203 def product_link(self, obj):
204 if obj.product:
205 return format_html(
206 '<a href="/admin/products/{}/{}/change/">{}</a>',
207 obj.content_type.model,
208 obj.object_id,
209 str(obj.product),
210 )
211 return '-'
213 product_link.short_description = 'Product'
215 def has_add_permission(self, request):
216 return False
218 def has_delete_permission(self, request, obj=None):
219 return request.user.is_superuser