first commit
This commit is contained in:
250
namecreate/admin.py
Normal file
250
namecreate/admin.py
Normal file
@@ -0,0 +1,250 @@
|
||||
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> '
|
||||
'<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.')
|
||||
Reference in New Issue
Block a user