almost finish migrate new circumstances

This commit is contained in:
2025-08-24 19:44:36 +09:00
parent 1ba305641e
commit fe5a044c82
67 changed files with 1194889 additions and 467 deletions

View File

@ -4,7 +4,7 @@ from django.shortcuts import render,redirect
from leaflet.admin import LeafletGeoAdmin
from leaflet.admin import LeafletGeoAdminMixin
from leaflet_admin_list.admin import LeafletAdminListMixin
from .models import RogUser, Location, SystemSettings, JoinedEvent, Favorite, TravelList, TravelPoint, ShapeLayers, Event, Location_line, Location_polygon, JpnAdminMainPerf, Useractions, CustomUser, GifuAreas, UserTracks, templocation, UserUpload, EventUser, GoalImages, CheckinImages, NewEvent2, Team, NewCategory, Entry, Member, TempUser,GifurogeRegister
from .models import RogUser, Location, Location2025, SystemSettings, JoinedEvent, Favorite, TravelList, TravelPoint, ShapeLayers, Event, Location_line, Location_polygon, JpnAdminMainPerf, Useractions, CustomUser, GifuAreas, UserTracks, templocation, UserUpload, EventUser, GoalImages, CheckinImages, NewEvent2, Team, NewCategory, Entry, Member, TempUser, GifurogeRegister, GpsLog, GpsCheckin, Checkpoint, Waypoint
from django.contrib.auth.admin import UserAdmin
from django.urls import path,reverse
from django.shortcuts import render
@ -1007,3 +1007,170 @@ admin.site.register(templocation, TempLocationAdmin)
admin.site.register(GoalImages, admin.ModelAdmin)
admin.site.register(CheckinImages, admin.ModelAdmin)
# GpsLogとその他の新しいモデルの登録
@admin.register(GpsLog)
class GpsLogAdmin(admin.ModelAdmin):
list_display = ['id', 'serial_number', 'zekken_number', 'event_code', 'cp_number', 'checkin_time']
list_filter = ['event_code', 'checkin_time', 'buy_flag', 'is_service_checked']
search_fields = ['zekken_number', 'event_code', 'cp_number']
readonly_fields = ['checkin_time', 'create_at', 'update_at']
@admin.register(GpsCheckin)
class GpsCheckinAdmin(admin.ModelAdmin):
list_display = ['id', 'zekken_number', 'event_code', 'cp_number', 'create_at']
list_filter = ['event_code', 'create_at', 'validate_location']
search_fields = ['zekken_number', 'event_code', 'cp_number']
readonly_fields = ['create_at']
@admin.register(Checkpoint)
class CheckpointAdmin(admin.ModelAdmin):
list_display = ['id', 'cp_name', 'cp_number', 'photo_point', 'buy_point']
search_fields = ['cp_name', 'cp_number']
list_filter = ['photo_point', 'buy_point']
readonly_fields = ['created_at', 'updated_at']
@admin.register(Waypoint)
class WaypointAdmin(admin.ModelAdmin):
list_display = ['id', 'entry', 'latitude', 'longitude', 'recorded_at']
search_fields = ['entry__team_name']
list_filter = ['recorded_at']
readonly_fields = ['created_at']
@admin.register(Location2025)
class Location2025Admin(LeafletGeoAdmin):
"""Location2025の管理画面"""
list_display = [
'cp_number', 'cp_name', 'event', 'total_point', 'is_active',
'csv_upload_date', 'created_at'
]
list_filter = [
'event', 'is_active', 'shop_closed', 'shop_shutdown',
'csv_upload_date', 'created_at'
]
search_fields = ['cp_name', 'address', 'description']
readonly_fields = [
'csv_source_file', 'csv_upload_date', 'csv_upload_user',
'created_at', 'updated_at', 'created_by', 'updated_by'
]
fieldsets = (
('基本情報', {
'fields': ('cp_number', 'event', 'cp_name', 'is_active', 'sort_order')
}),
('位置情報', {
'fields': ('latitude', 'longitude', 'location', 'address')
}),
('ポイント設定', {
'fields': ('cp_point', 'photo_point', 'buy_point')
}),
('チェックイン設定', {
'fields': ('checkin_radius', 'auto_checkin')
}),
('営業情報', {
'fields': ('shop_closed', 'shop_shutdown', 'opening_hours')
}),
('詳細情報', {
'fields': ('phone', 'website', 'description')
}),
('CSV情報', {
'fields': ('csv_source_file', 'csv_upload_date', 'csv_upload_user'),
'classes': ('collapse',)
}),
('管理情報', {
'fields': ('created_at', 'updated_at', 'created_by', 'updated_by'),
'classes': ('collapse',)
}),
)
# CSV一括アップロード機能
change_list_template = 'admin/location2025/change_list.html'
def get_urls(self):
from django.urls import path
urls = super().get_urls()
custom_urls = [
path('upload-csv/', self.upload_csv_view, name='location2025_upload_csv'),
path('export-csv/', self.export_csv_view, name='location2025_export_csv'),
]
return custom_urls + urls
def upload_csv_view(self, request):
"""CSVアップロード画面"""
if request.method == 'POST':
if 'csv_file' in request.FILES and 'event' in request.POST:
csv_file = request.FILES['csv_file']
event_id = request.POST['event']
try:
from .models import NewEvent2
event = NewEvent2.objects.get(id=event_id)
# CSVインポート実行
result = Location2025.import_from_csv(
csv_file,
event,
user=request.user
)
# 結果メッセージ
if result['errors']:
messages.warning(
request,
f"インポート完了: 作成{result['created']}件, 更新{result['updated']}件, "
f"エラー{len(result['errors'])}件 - {'; '.join(result['errors'][:5])}"
)
else:
messages.success(
request,
f"CSVインポートが完了しました。作成: {result['created']}件, 更新: {result['updated']}"
)
except Exception as e:
messages.error(request, f"CSVインポートエラー: {str(e)}")
return redirect('..')
# フォーム表示
from .models import NewEvent2
events = NewEvent2.objects.filter(event_active=True).order_by('-created_at')
return render(request, 'admin/location2025/upload_csv.html', {
'events': events,
'title': 'チェックポイントCSVアップロード'
})
def export_csv_view(self, request):
"""CSVエクスポート"""
import csv
from django.http import HttpResponse
from django.utils import timezone
response = HttpResponse(content_type='text/csv; charset=utf-8')
response['Content-Disposition'] = f'attachment; filename="checkpoints_{timezone.now().strftime("%Y%m%d_%H%M%S")}.csv"'
# BOM付きUTF-8で出力
response.write('\ufeff')
writer = csv.writer(response)
writer.writerow([
'cp_number', 'cp_name', 'latitude', 'longitude', 'cp_point',
'photo_point', 'buy_point', 'address', 'phone', 'description'
])
queryset = self.get_queryset(request)
for obj in queryset:
writer.writerow([
obj.cp_number, obj.cp_name, obj.latitude, obj.longitude,
obj.cp_point, obj.photo_point, obj.buy_point,
obj.address, obj.phone, obj.description
])
return response
def save_model(self, request, obj, form, change):
"""保存時にユーザー情報を自動設定"""
if not change: # 新規作成時
obj.created_by = request.user
obj.updated_by = request.user
super().save_model(request, obj, form, change)