mirror of
https://expo.survex.com/repositories/troggle/.git
synced 2025-12-17 23:47:12 +00:00
fixed many problems in creating new entrances
This commit is contained in:
@@ -475,6 +475,30 @@ def edit_entrance(request, path="", caveslug=None, entslug=None):
|
||||
GET RID of all this entranceletter stuff. Far too overcomplexified.
|
||||
We don't need it. Just the entrance slug is fine, then check uniqueness.
|
||||
"""
|
||||
def check_new_slugname_ok(slug, letter):
|
||||
"""In Nov.2023 it is possible to create a 2nd entrance and not set an entrance letter,
|
||||
which leads to a constraint uniqueness crash. FIX THIS.
|
||||
The letter may be set to an existing letter, OR it may be unset, but there may
|
||||
be an existing unlettered single entrance. Both of these will crash unless fixed.
|
||||
"""
|
||||
slugname = f"{slug}{letter}"
|
||||
nents = Entrance.objects.filter(slug=slugname).count()
|
||||
print(f"NUM ents {slugname=} => {nents}")
|
||||
if nents == 0:
|
||||
# looks good, but we need to check the CaveaAndEntrance object too
|
||||
e = entrance #Entrance.objects.get(slug=slugname) # does not exist yet!
|
||||
gcl = GetCaveLookup()
|
||||
c = gcl[slug]
|
||||
nce = CaveAndEntrance.objects.filter(cave=c, entrance=e).count()
|
||||
if nce == 0 :
|
||||
return slugname, letter
|
||||
|
||||
# That entrance already exists, or the CE does, OK.. do recursive call, starting at "b"
|
||||
if letter =="":
|
||||
return check_new_slugname_ok(slug, "b")
|
||||
else:
|
||||
nextletter = chr(ord(letter)+1)
|
||||
return check_new_slugname_ok(slug, nextletter)
|
||||
|
||||
try:
|
||||
cave = Cave.objects.get(caveslug__slug=caveslug)
|
||||
@@ -495,42 +519,60 @@ def edit_entrance(request, path="", caveslug=None, entslug=None):
|
||||
caveAndEntrance = CaveAndEntrance.objects.get(entrance=entrance, cave=cave)
|
||||
entlettereditable = False
|
||||
else:
|
||||
caveAndEntrance = CaveAndEntrance(cave=cave, entrance=Entrance())
|
||||
caveAndEntrance = CaveAndEntrance(cave=cave, entrance=Entrance()) # creates a new Entrance object as well as a new CE object
|
||||
entlettereditable = True
|
||||
|
||||
if caveAndEntrance.entranceletter == "" and cave.entrances().count() > 0 :
|
||||
ce = caveAndEntrance
|
||||
if ce.entranceletter == "" and cave.entrances().count() > 0 :
|
||||
# this should not be blank on a multiple-entrance cave
|
||||
# but it doesn't trigger the entrance letter form unless entletter has a value
|
||||
entlettereditable = True
|
||||
entlettereditable = True # but the user has to remember to actually set it...
|
||||
|
||||
print(f"{entlettereditable=}")
|
||||
# if the entletter is no editable, then the entletterform does not appear and so is always invalid.
|
||||
# if the entletter is not editable, then the entletterform does not appear and so is always invalid.
|
||||
|
||||
if request.POST:
|
||||
print(f"POST Online edit of entrance: '{entrance}' where {cave=}")
|
||||
entform = EntranceForm(request.POST, instance=entrance)
|
||||
|
||||
if not entlettereditable:
|
||||
entranceletter = caveAndEntrance.entranceletter
|
||||
ce = caveAndEntrance
|
||||
entranceletter = ce.entranceletter
|
||||
else:
|
||||
entletterform = EntranceLetterForm(request.POST, instance=caveAndEntrance)
|
||||
entletterform = EntranceLetterForm(request.POST, instance=ce)
|
||||
if entletterform.is_valid():
|
||||
ce = entletterform.save(commit=False)
|
||||
entranceletter = entletterform.cleaned_data["entranceletter"]
|
||||
message = f"- POST valid {caveslug=} {entslug=} {path=} entletterform valid \n {entletterform=}."
|
||||
print(message)
|
||||
else:
|
||||
print(f"- POST INVALID {caveslug=} {entslug=} {path=} entletterform invalid.")
|
||||
return render(request, "errors/badslug.html", {"badslug": "entletter problem in edit_entrances()"})
|
||||
# if entform.is_valid() and entletterform.is_valid():
|
||||
if entform.is_valid():
|
||||
# maybe this doesn't matter? It just means entranceletter unset ?
|
||||
# probably because 'Cave and entrance with this Cave and Entranceletter already exists.'
|
||||
message = f"- POST INVALID {caveslug=} {entslug=} {path=} entletterform invalid \n{entletterform.errors=}\n{entletterform=}."
|
||||
print(message)
|
||||
# if entletterform.errors:
|
||||
# for field in entletterform:
|
||||
# for error in field.errors:
|
||||
# print(f"ERR {field=} {error=}")
|
||||
# return render(request, "errors/generic.html", {"message": message})
|
||||
entranceletter=""
|
||||
|
||||
if not entform.is_valid():
|
||||
message = f"- POST INVALID {caveslug=} {entslug=} {path=} entform valid:{entform.is_valid()} entletterform valid:{entletterform.is_valid()}"
|
||||
entrance = entform.save(commit=False)
|
||||
print(message)
|
||||
return render(request, "errors/generic.html", {"message": message})
|
||||
else:
|
||||
|
||||
print(f"- POST {caveslug=} {entslug=} {entranceletter=} {path=}")
|
||||
if entslug is None:
|
||||
# we are creating a new entrance
|
||||
if entranceletter:
|
||||
slugname = cave.slug() + entranceletter
|
||||
print(f"- POST letter {entranceletter=}")
|
||||
slugname, letter = check_new_slugname_ok(cave.slug(), entranceletter)
|
||||
else:
|
||||
slugname = cave.slug()
|
||||
slugname, letter = check_new_slugname_ok(cave.slug(), "")
|
||||
ce.entranceletter = letter
|
||||
entrance = ce.entrance # the one we created earlier
|
||||
|
||||
entrance.slug = slugname
|
||||
entrance.cached_primary_slug = slugname
|
||||
entrance.filename = slugname + ".html"
|
||||
@@ -541,41 +583,48 @@ def edit_entrance(request, path="", caveslug=None, entslug=None):
|
||||
try:
|
||||
entrance.save()
|
||||
except:
|
||||
# fails with uniqueness constraint failure. Which is on CaveAndEntrance, not just on entrance, which is bizarre.
|
||||
# fails with uniqueness constraint failure. Which is on CaveAndEntrance, not just on entrance,
|
||||
# which is confusing to a user who is just editing an Entrance.
|
||||
# Can happen when user specifies an existing letter! (or none, when they should set one)
|
||||
print(f"SAVE EXCEPTION FAIL {entrance=}")
|
||||
print(f"CAVE {cave}")
|
||||
for ce in cave.entrances():
|
||||
print(f"CAVE:{ce.cave} - ENT:{ce.entrance} - LETTER:'{ce.entranceletter}'")
|
||||
raise
|
||||
ce.entrance = entrance
|
||||
# try not to do this:
|
||||
# UNIQUE constraint failed: core_caveandentrance.cave_id, core_caveandentrance.entranceletter
|
||||
ce.save()
|
||||
|
||||
entrance_file = entrance.file_output()
|
||||
cave_file = cave.file_output()
|
||||
|
||||
|
||||
print(f"- POST WRITE letter: '{ce}' {entrance=}")
|
||||
write_and_commit([entrance_file, cave_file], f"Online edit of entrance {entrance.slug}")
|
||||
return HttpResponseRedirect("/" + cave.url)
|
||||
else: # one of the forms is not valid
|
||||
print(f"- POST INVALID {caveslug=} {entslug=} {path=} entform valid:{entform.is_valid()} entletterform valid:{entletterform.is_valid()}")
|
||||
if write_and_commit([entrance_file, cave_file], f"Online edit of entrance {entrance.slug}"):
|
||||
return HttpResponseRedirect("/" + cave.url)
|
||||
else:
|
||||
efilepath, econtent, eencoding = entrance_file
|
||||
cfilepath, ccontent, cencoding = cave_file
|
||||
message = f"- FAIL write_and_commit \n entr:'{efilepath}'\n cave:'{cfilepath}'"
|
||||
print(message)
|
||||
return render(request, "errors/generic.html", {"message": message})
|
||||
|
||||
else: # GET the page, not POST, or if either of the forms were invalid when POSTed
|
||||
entletterform = None
|
||||
entletter = ""
|
||||
print(f"ENTRANCE in db: entranceletter = '{caveAndEntrance.entranceletter}'")
|
||||
print(f"ENTRANCE in db: entranceletter = '{ce.entranceletter}'")
|
||||
if entrance:
|
||||
# re-read entrance data from file.
|
||||
filename = str(entrance.slug +".html")
|
||||
ent = read_entrance(filename, ent=entrance)
|
||||
print(f"ENTRANCE from file: entranceletter = '{caveAndEntrance.entranceletter}'")
|
||||
print(f"ENTRANCE from file: entranceletter = '{ce.entranceletter}'")
|
||||
|
||||
entform = EntranceForm(instance=entrance)
|
||||
if entslug is None:
|
||||
entletterform = EntranceLetterForm()
|
||||
# print(f" Getting entletter from EntranceLetterForm")
|
||||
else:
|
||||
entletter = caveAndEntrance.entranceletter
|
||||
entletter = ce.entranceletter
|
||||
if entletter == "":
|
||||
entletterform = EntranceLetterForm()
|
||||
print(f" Blank value: getting entletter from EntranceLetterForm")
|
||||
@@ -619,7 +668,14 @@ def cave_debug(request):
|
||||
{"ents": ents},
|
||||
)
|
||||
|
||||
|
||||
def caveslist(request):
|
||||
caves = Cave.objects.all()
|
||||
print("CAVESLIST")
|
||||
return render(
|
||||
request,
|
||||
"caveslist.html",
|
||||
{"caves": caves},
|
||||
)
|
||||
def get_entrances(request, caveslug):
|
||||
try:
|
||||
cave = Cave.objects.get(caveslug__slug=caveslug)
|
||||
|
||||
Reference in New Issue
Block a user