Files
ShooterHub/apps/gears/admin.py
2026-04-02 11:24:30 +02:00

172 lines
5.8 KiB
Python

from django.contrib import admin
from django.utils.translation import gettext_lazy as _
from .models import (
Ammo,
Bipod,
Brass,
Bullet,
Firearm,
Magazine,
Powder,
Primer,
ReloadedAmmoBatch,
ReloadRecipe,
Rig,
RigItem,
Scope,
Suppressor,
UserGear,
)
class GearAdminBase(admin.ModelAdmin):
list_display = ('brand', 'model_name', 'status', 'submitted_by', 'reviewed_by', 'created_at')
list_filter = ('status',)
search_fields = ('brand', 'model_name')
readonly_fields = ('gear_type', 'submitted_by', 'reviewed_by', 'reviewed_at', 'created_at', 'updated_at')
actions = ['verify_gears', 'reject_gears']
@admin.action(description=_('Mark selected gears as Verified'))
def verify_gears(self, request, queryset):
for gear in queryset:
gear.verify(reviewed_by=request.user)
@admin.action(description=_('Mark selected gears as Rejected'))
def reject_gears(self, request, queryset):
for gear in queryset:
gear.reject(reviewed_by=request.user)
@admin.register(Firearm)
class FirearmAdmin(GearAdminBase):
list_display = GearAdminBase.list_display + ('firearm_type', 'caliber')
list_filter = GearAdminBase.list_filter + ('firearm_type',)
@admin.register(Scope)
class ScopeAdmin(GearAdminBase):
list_display = GearAdminBase.list_display + ('magnification_min', 'magnification_max', 'objective_diameter_mm')
@admin.register(Suppressor)
class SuppressorAdmin(GearAdminBase):
list_display = GearAdminBase.list_display + ('max_caliber', 'thread_pitch')
@admin.register(Bipod)
class BipodAdmin(GearAdminBase):
list_display = GearAdminBase.list_display + ('attachment_type',)
@admin.register(Magazine)
class MagazineAdmin(GearAdminBase):
list_display = GearAdminBase.list_display + ('caliber', 'capacity')
@admin.register(UserGear)
class UserGearAdmin(admin.ModelAdmin):
list_display = ('user', 'gear', 'nickname', 'serial_number', 'added_at')
search_fields = ('user__email', 'gear__brand', 'gear__model_name', 'nickname')
raw_id_fields = ('user', 'gear')
class RigItemInline(admin.TabularInline):
model = RigItem
extra = 0
raw_id_fields = ('user_gear',)
@admin.register(Rig)
class RigAdmin(admin.ModelAdmin):
list_display = ('name', 'user', 'created_at')
search_fields = ('name', 'user__email')
inlines = [RigItemInline]
@admin.register(RigItem)
class RigItemAdmin(admin.ModelAdmin):
list_display = ('rig', 'user_gear', 'role')
list_filter = ('role',)
search_fields = ('rig__name', 'user_gear__gear__brand', 'user_gear__gear__model_name')
raw_id_fields = ('rig', 'user_gear')
# ── Ammo catalog ──────────────────────────────────────────────────────────────
@admin.register(Ammo)
class AmmoAdmin(admin.ModelAdmin):
list_display = ('brand', 'name', 'caliber', 'bullet_weight_gr', 'bullet_type', 'status', 'submitted_by')
list_filter = ('status', 'bullet_type', 'caliber', 'case_material')
search_fields = ('brand', 'name', 'caliber')
readonly_fields = ('submitted_by', 'reviewed_by', 'reviewed_at', 'created_at', 'updated_at')
raw_id_fields = ('submitted_by', 'reviewed_by')
actions = ['verify_ammo', 'reject_ammo']
@admin.action(description=_('Mark selected ammo as Verified'))
def verify_ammo(self, request, queryset):
for ammo in queryset:
ammo.verify(reviewed_by=request.user)
@admin.action(description=_('Mark selected ammo as Rejected'))
def reject_ammo(self, request, queryset):
for ammo in queryset:
ammo.reject(reviewed_by=request.user)
# ── Reloading components ───────────────────────────────────────────────────────
@admin.register(Primer)
class PrimerAdmin(admin.ModelAdmin):
list_display = ('brand', 'name', 'size')
list_filter = ('size',)
search_fields = ('brand', 'name')
@admin.register(Brass)
class BrassAdmin(admin.ModelAdmin):
list_display = ('brand', 'caliber', 'primer_pocket', 'trim_length_mm')
list_filter = ('caliber',)
search_fields = ('brand', 'caliber')
@admin.register(Bullet)
class BulletAdmin(admin.ModelAdmin):
list_display = ('brand', 'model_name', 'weight_gr', 'bullet_type', 'diameter_mm')
list_filter = ('bullet_type',)
search_fields = ('brand', 'model_name')
@admin.register(Powder)
class PowderAdmin(admin.ModelAdmin):
list_display = ('brand', 'name', 'powder_type', 'burn_rate_index')
list_filter = ('powder_type',)
search_fields = ('brand', 'name')
ordering = ('burn_rate_index',)
# ── Reload development ────────────────────────────────────────────────────────
class ReloadedAmmoBatchInline(admin.TabularInline):
model = ReloadedAmmoBatch
extra = 0
show_change_link = True
fields = ('powder', 'powder_charge_gr', 'quantity', 'oal_mm', 'loaded_at')
raw_id_fields = ('powder',)
@admin.register(ReloadRecipe)
class ReloadRecipeAdmin(admin.ModelAdmin):
list_display = ('name', 'user', 'caliber', 'primer', 'brass', 'bullet', 'created_at')
search_fields = ('name', 'user__email', 'caliber')
raw_id_fields = ('user', 'primer', 'brass', 'bullet')
inlines = [ReloadedAmmoBatchInline]
@admin.register(ReloadedAmmoBatch)
class ReloadedAmmoBatchAdmin(admin.ModelAdmin):
list_display = ('recipe', 'powder', 'powder_charge_gr', 'quantity', 'loaded_at')
search_fields = ('recipe__name', 'powder__name')
list_filter = ('loaded_at',)
raw_id_fields = ('recipe', 'powder')