mirror of
https://expo.survex.com/repositories/troggle/.git
synced 2026-02-08 13:18:15 +00:00
more progress to better serializer
This commit is contained in:
@@ -327,9 +327,6 @@ def shared_use_machine(request):
|
||||
print(f" - shared use cookie exists, but has wrong value: '{cookie_txt}' not '{PUBLIC_LAPTOP_COOKIE_TEXT}'")
|
||||
return True
|
||||
|
||||
|
||||
|
||||
|
||||
def get_cookie(request):
|
||||
"""The initial idea of having a default turned out to be a bad idea as people just ignore the field.
|
||||
If the default value is blank, then the form validation code makes the user type something in.
|
||||
@@ -539,6 +536,18 @@ class WriteAndCommitError(Exception):
|
||||
def __str__(self):
|
||||
return f"WriteAndCommitError: {self.message}"
|
||||
|
||||
# Custom JSON Encoder to handle non-serializable types
|
||||
class CustomJSONEncoder(json.JSONEncoder):
|
||||
def default(self, obj):
|
||||
# Convert datetime objects to ISO 8601 string format
|
||||
if isinstance(obj, datetime):
|
||||
return obj.isoformat()
|
||||
# Convert Decimal objects to string
|
||||
if isinstance(obj, Decimal):
|
||||
# Use str() for perfect precision, or float() for numerical representation
|
||||
return str(obj)
|
||||
# Let the base class handle other types
|
||||
return json.JSONEncoder.default(self, obj)
|
||||
|
||||
"""The following is a Bard converted version of Radosts's MIT copyrighted Javascript on 2023-10-27
|
||||
with hand-editing.
|
||||
|
||||
@@ -1,20 +1,24 @@
|
||||
import json
|
||||
import re
|
||||
|
||||
from datetime import datetime
|
||||
from decimal import Decimal
|
||||
|
||||
|
||||
from django.contrib.auth.models import User
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.core.serializers import serialize
|
||||
from django.db.models import Q
|
||||
from django.forms.models import model_to_dict
|
||||
from django.shortcuts import redirect, render
|
||||
from django.views.generic.list import ListView
|
||||
from django.contrib.auth.models import User
|
||||
|
||||
|
||||
import troggle.settings as settings
|
||||
from troggle.core.models.logbooks import QM, LogbookEntry, PersonLogEntry, writelogbook
|
||||
from troggle.core.models.survex import SurvexBlock, SurvexFile
|
||||
from troggle.core.models.troggle import Expedition, Person
|
||||
from troggle.core.models.wallets import Wallet
|
||||
from troggle.core.utils import TROG, current_expo, add_commit, git_commit, git_add, get_editor
|
||||
from troggle.core.utils import TROG, current_expo, add_commit, git_commit, git_add, get_editor, ensure_dir_exists, CustomJSONEncoder
|
||||
from troggle.parsers.imports import import_logbook
|
||||
|
||||
"""These views are for logbook items when they appear in an 'expedition' page
|
||||
@@ -399,6 +403,8 @@ def write_entries(entries, year, editor):
|
||||
"""
|
||||
|
||||
def write_json_file():
|
||||
# uses filepath, jsondict from context
|
||||
|
||||
try:
|
||||
with open(filepath, 'w', encoding='utf-8') as json_f:
|
||||
json.dump(jsondict, json_f, indent=1)
|
||||
@@ -410,78 +416,67 @@ def write_entries(entries, year, editor):
|
||||
print(f"CANNOT write this file {filepath}. Exception dumping json. Ask a nerd to fix this: {e}")
|
||||
raise e
|
||||
|
||||
def serialize_logentry():
|
||||
# REPLACE this with hand-built serializer which includes .author, .who which were added to the entries but re not in the model Class directly
|
||||
# see below for Gemini code to do that. Going to bed now.
|
||||
jsondict = serialize("json", [le], fields=('slug', 'date', 'expedition', 'title', 'cave', 'place', 'other_people', 'time_underground', 'text'))
|
||||
return jsondict
|
||||
|
||||
dirpath = settings.EXPOWEB / "years" / year / LOGBOOK_ENTRIES
|
||||
dirpath.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
for le in entries:
|
||||
filename = f"{le.slug}-{le.pk:03}.json"
|
||||
filepath = dirpath / filename
|
||||
# description = f" {le.slug} :: {le.date} - {le.title}"
|
||||
ensure_dir_exists(filepath)
|
||||
|
||||
# REPLACE this with hand-built serializer which includes .author, .who which were added to the entries but re not in the model Class directly
|
||||
# see below for Gemini code to do that. Going to bed now.
|
||||
jsondict = serialize("json", [le], fields=('slug', 'date', 'expedition', 'title', 'cave', 'place', 'other_people', 'time_underground', 'text'))
|
||||
|
||||
jsondict = serialize_logentry()
|
||||
write_json_file()
|
||||
git_add(filename, dirpath)
|
||||
|
||||
commit_msg = f"Exporting logbook entries as individual files"
|
||||
commit_msg = f"Exporting {len(entries)} logbook entries as individual files."
|
||||
git_commit(dirpath, commit_msg, editor)
|
||||
return True
|
||||
|
||||
# Gemini has the answer, get what I need from this:
|
||||
|
||||
# from django.http import JsonResponse, HttpResponse
|
||||
# # from .models import LogbookEntry, PersonLogEntry, Person # Import your models
|
||||
# from django.forms.models import model_to_dict
|
||||
# from datetime import datetime
|
||||
# import json
|
||||
# from decimal import Decimal
|
||||
|
||||
# # Re-using the custom encoder from the previous suggestion for robust date/decimal handling
|
||||
# class CustomJSONEncoder(json.JSONEncoder):
|
||||
# def default(self, obj):
|
||||
# if isinstance(obj, datetime):
|
||||
# return obj.isoformat()
|
||||
# if isinstance(obj, Decimal):
|
||||
# return str(obj)
|
||||
# return json.JSONEncoder.default(self, obj)
|
||||
|
||||
# def export_entry_with_author_details(request, entry_id):
|
||||
# try:
|
||||
# # 1. Get the LogbookEntry instance
|
||||
# entry = LogbookEntry.objects.get(pk=entry_id)
|
||||
|
||||
# # 2. Get the related PersonLogEntry and Person (Author)
|
||||
# # Use .select_related() for efficiency
|
||||
# author_link = PersonLogEntry.objects.select_related('person').get(
|
||||
# entry=entry,
|
||||
# is_author=True # Adjust filter based on your logic
|
||||
# )
|
||||
# author = author_link.person
|
||||
|
||||
# except (LogbookEntry.DoesNotExist, PersonLogEntry.DoesNotExist):
|
||||
# return HttpResponse(f'Entry or Author not found for ID {entry_id}', status=404)
|
||||
|
||||
# # 3. Manually create the nested dictionary structure
|
||||
# # Use model_to_dict for easy extraction of the simple fields
|
||||
|
||||
# # Author data (specify fields you want to expose)
|
||||
# author_data = model_to_dict(author, fields=['id', 'first_name', 'last_name', 'email'])
|
||||
|
||||
# # Entry data (specify fields you want to expose)
|
||||
# entry_data = model_to_dict(entry, fields=['id', 'title', 'content', 'date_created'])
|
||||
|
||||
# # Nest the author data inside the entry data
|
||||
# entry_data['author'] = author_data
|
||||
|
||||
# # Add data from the intermediate model if needed (e.g., the date the person was added)
|
||||
# entry_data['author_assignment_date'] = author_link.date_assigned.isoformat()
|
||||
|
||||
|
||||
# # 4. Return the custom dictionary using JsonResponse
|
||||
# return JsonResponse(
|
||||
# entry_data,
|
||||
# encoder=CustomJSONEncoder,
|
||||
# safe=False # Set to True if entry_data was a list/QuerySet
|
||||
# )
|
||||
def export_entry_with_author_details(request, entry_id):
|
||||
try:
|
||||
# 1. Get the LogbookEntry instance
|
||||
entry = LogbookEntry.objects.get(pk=entry_id)
|
||||
|
||||
# 2. Get the related PersonLogEntry and Person (Author)
|
||||
# Use .select_related() for efficiency
|
||||
author_link = PersonLogEntry.objects.select_related('person').get(
|
||||
entry=entry,
|
||||
is_author=True # Adjust filter based on your logic
|
||||
)
|
||||
author = author_link.person
|
||||
|
||||
except (LogbookEntry.DoesNotExist, PersonLogEntry.DoesNotExist):
|
||||
return HttpResponse(f'Entry or Author not found for ID {entry_id}', status=404)
|
||||
|
||||
# 3. Manually create the nested dictionary structure
|
||||
# Use model_to_dict for easy extraction of the simple fields
|
||||
|
||||
# Author data (specify fields you want to expose)
|
||||
author_data = model_to_dict(author, fields=['id', 'first_name', 'last_name', 'email'])
|
||||
|
||||
# Entry data (specify fields you want to expose)
|
||||
entry_data = model_to_dict(entry, fields=['id', 'title', 'content', 'date_created'])
|
||||
|
||||
# Nest the author data inside the entry data
|
||||
entry_data['author'] = author_data
|
||||
|
||||
# Add data from the intermediate model if needed (e.g., the date the person was added)
|
||||
entry_data['author_assignment_date'] = author_link.date_assigned.isoformat()
|
||||
|
||||
|
||||
# 4. Return the custom dictionary using JsonResponse
|
||||
return JsonResponse(
|
||||
entry_data,
|
||||
encoder=CustomJSONEncoder,
|
||||
safe=False # Set to True if entry_data was a list/QuerySet
|
||||
)
|
||||
Reference in New Issue
Block a user