Files
insta/namecreate/admin.py
Beyhan Oğur 2be3a313ad first commit
2026-04-26 22:26:46 +03:00

251 lines
9.0 KiB
Python

import io
from django.contrib import admin
from django.contrib import messages
from django.core.management import call_command
from django.http import HttpResponseRedirect
from django.urls import path, reverse
from django.utils.html import format_html
from .models import TrainingJob, NameVocab, GeneratedPerson
class GeneratedPersonInline(admin.TabularInline):
model = GeneratedPerson
extra = 0
fields = (
'first_name', 'last_name', 'username', 'username_locked',
'birth_date', 'gender', 'confidence', 'generated_at'
)
readonly_fields = (
'first_name', 'last_name', 'username', 'username_locked',
'birth_date', 'gender', 'confidence', 'generated_at'
)
can_delete = False
show_change_link = True
@admin.register(TrainingJob)
class TrainingJobAdmin(admin.ModelAdmin):
list_display = (
'id',
'task_id',
'status',
'model_type',
'model_file_exists',
'generated_person_count',
'accuracy',
'created_at',
'completed_at',
)
list_filter = ('status', 'model_type', 'created_at')
search_fields = ('task_id', 'error_message')
readonly_fields = (
'task_id',
'created_at',
'started_at',
'completed_at',
'model_version',
'model_file_exists',
'generated_person_count',
)
actions = (
'generate_100_statistical_action',
'generate_100_llm_action',
'generate_1000_statistical_action',
'generate_1000_llm_action',
)
inlines = (GeneratedPersonInline,)
fieldsets = (
('Görev Bilgisi', {
'fields': ('task_id', 'status', 'created_at', 'started_at', 'completed_at')
}),
('Model', {
'fields': ('model_type', 'model_version', 'model_path', 'model_file_exists')
}),
('Uretilen Kayitlar', {
'fields': ('generated_person_count',)
}),
('Metrikler', {
'fields': ('accuracy', 'precision', 'recall', 'f1_score')
}),
('Go Servisi', {
'fields': ('go_service_notified',)
}),
('Hata', {
'fields': ('error_message',),
'classes': ('collapse',)
}),
)
def model_file_exists(self, obj):
return bool(obj.model_path and __import__('os').path.exists(obj.model_path))
model_file_exists.boolean = True
model_file_exists.short_description = 'Model dosyasi var'
def generated_person_count(self, obj):
return obj.generated_persons.count()
generated_person_count.short_description = 'Uretilen kisi sayisi'
def _run_generate_persons(self, request, queryset, count, use_llm):
total_jobs = queryset.count()
ok_jobs = 0
for job in queryset:
try:
out = io.StringIO()
kwargs = {
'count': count,
'job_id': job.pk,
'stdout': out,
}
if use_llm:
kwargs['use_llm'] = True
else:
kwargs['no_llm'] = True
call_command('generate_persons', **kwargs)
ok_jobs += 1
except Exception as exc:
self.message_user(
request,
f'Job id={job.pk} icin uretim hatasi: {exc}',
level=messages.ERROR,
)
mode = 'LLM (fallback ile)' if use_llm else 'Istatistiksel'
self.message_user(
request,
f'Uretim tamamlandi. Mod: {mode}. Basarili job: {ok_jobs}/{total_jobs}. Her job icin {count} kayit.',
level=messages.SUCCESS,
)
@admin.action(description='Secili job(lar) icin 100 kisi uret (Istatistiksel)')
def generate_100_statistical_action(self, request, queryset):
self._run_generate_persons(request, queryset, count=100, use_llm=False)
@admin.action(description='Secili job(lar) icin 100 kisi uret (LLM + fallback)')
def generate_100_llm_action(self, request, queryset):
self._run_generate_persons(request, queryset, count=100, use_llm=True)
@admin.action(description='Secili job(lar) icin 1000 kisi uret (Istatistiksel)')
def generate_1000_statistical_action(self, request, queryset):
self._run_generate_persons(request, queryset, count=1000, use_llm=False)
@admin.action(description='Secili job(lar) icin 1000 kisi uret (LLM + fallback)')
def generate_1000_llm_action(self, request, queryset):
self._run_generate_persons(request, queryset, count=1000, use_llm=True)
@admin.register(NameVocab)
class NameVocabAdmin(admin.ModelAdmin):
list_display = ('name', 'name_type', 'gender', 'origin', 'frequency')
list_filter = ('origin', 'name_type', 'gender')
search_fields = ('name',)
ordering = ('origin', '-frequency')
@admin.register(GeneratedPerson)
class GeneratedPersonAdmin(admin.ModelAdmin):
list_display = (
'first_name', 'last_name', 'username', 'username_locked',
'birth_date', 'gender', 'confidence', 'generated_at', 'username_ops'
)
list_filter = ('gender', 'username_locked', 'generated_at')
search_fields = ('first_name', 'last_name', 'username')
readonly_fields = ('generated_at',)
actions = ('regenerate_username_action', 'lock_username_action', 'unlock_username_action')
def get_urls(self):
urls = super().get_urls()
custom_urls = [
path(
'<int:person_id>/regenerate-username/',
self.admin_site.admin_view(self.regenerate_username_view),
name='namecreate_generatedperson_regenerate_username',
),
path(
'<int:person_id>/toggle-username-lock/',
self.admin_site.admin_view(self.toggle_username_lock_view),
name='namecreate_generatedperson_toggle_username_lock',
),
]
return custom_urls + urls
def regenerate_username_view(self, request, person_id):
person = self.get_object(request, person_id)
if person is None:
self.message_user(request, 'Kayit bulunamadi.', level=messages.ERROR)
return HttpResponseRedirect('../')
if person.username_locked:
self.message_user(request, 'Username kilitli. Once kilidi acin.', level=messages.WARNING)
return HttpResponseRedirect('../../')
old_username = person.username
person.regenerate_username(save=True)
self.message_user(
request,
f'Username guncellendi: {old_username} -> {person.username}',
level=messages.SUCCESS,
)
return HttpResponseRedirect('../../')
def toggle_username_lock_view(self, request, person_id):
person = self.get_object(request, person_id)
if person is None:
self.message_user(request, 'Kayit bulunamadi.', level=messages.ERROR)
return HttpResponseRedirect('../')
person.username_locked = not person.username_locked
person.save(update_fields=['username_locked'])
state = 'kilitlendi' if person.username_locked else 'kilidi acildi'
self.message_user(request, f'Username {state}.', level=messages.SUCCESS)
return HttpResponseRedirect('../../')
def username_ops(self, obj):
regen_url = reverse('admin:namecreate_generatedperson_regenerate_username', args=[obj.pk])
lock_url = reverse('admin:namecreate_generatedperson_toggle_username_lock', args=[obj.pk])
lock_label = 'Kilidi ac' if obj.username_locked else 'Kilitle'
return format_html(
'<a class="button" href="{}">Yeniden uret</a>&nbsp;'
'<a class="button" href="{}">{}</a>',
regen_url,
lock_url,
lock_label,
)
username_ops.short_description = 'Islemler'
@admin.action(description='Secili kayitlarda username yeniden uret')
def regenerate_username_action(self, request, queryset):
used_usernames = set(
GeneratedPerson.objects.exclude(username='').values_list('username', flat=True)
)
updated = 0
skipped = 0
for person in queryset:
if person.username_locked:
skipped += 1
continue
used_usernames.discard(person.username)
person.regenerate_username(used_usernames=used_usernames, force=True, save=True)
updated += 1
self.message_user(
request,
f'{updated} kayitta username yeniden uretildi. Kilitli oldugu icin atlanan: {skipped}.'
)
@admin.action(description='Secili kayitlarda username kilitle')
def lock_username_action(self, request, queryset):
count = queryset.update(username_locked=True)
self.message_user(request, f'{count} kayitta username kilitlendi.')
@admin.action(description='Secili kayitlarda username kilidini ac')
def unlock_username_action(self, request, queryset):
count = queryset.update(username_locked=False)
self.message_user(request, f'{count} kayitta username kilidi acildi.')