From d8b1d59b1221ac7885d6cf1b90cc2954c9b70139 Mon Sep 17 00:00:00 2001 From: Philip Sargent Date: Wed, 14 Apr 2021 16:28:30 +0100 Subject: [PATCH] Cave and Entrance forms tuned to user needs --- core/forms.py | 78 ++++++++++++++++++++++++------------- core/models/caves.py | 28 +++++++------ core/views/caves.py | 41 +++++++++++++------ templates/editcave2.html | 6 +-- templates/editentrance.html | 9 +++-- 5 files changed, 104 insertions(+), 58 deletions(-) diff --git a/core/forms.py b/core/forms.py index f435e4c..d2eddd3 100644 --- a/core/forms.py +++ b/core/forms.py @@ -16,20 +16,29 @@ Some are not used and need renovating or destroying. ''' class CaveForm(ModelForm): - underground_description = forms.CharField(required = False, widget=forms.Textarea()) - explorers = forms.CharField(required = False, widget=forms.Textarea()) - equipment = forms.CharField(required = False, widget=forms.Textarea()) - survey = forms.CharField(required = False, widget=forms.Textarea()) - kataster_status = forms.CharField(required = False, widget=forms.Textarea()) - underground_centre_line = forms.CharField(required = False, widget=forms.Textarea()) - notes = forms.CharField(required = False, widget=forms.Textarea()) - references = forms.CharField(required = False, widget=forms.Textarea()) - url = forms.CharField(required = True) + '''Only those fields for which we want to override defaults are listed here + the other fields are present on the form, but use the default presentaiton style + ''' + official_name = forms.CharField(required = False, widget=forms.TextInput(attrs={'size': '45'})) + underground_description = forms.CharField(required = False, widget=forms.Textarea(attrs={'rows':9})) + explorers = forms.CharField(required = False, widget=forms.Textarea(attrs={'rows':2})) + equipment = forms.CharField(required = False, widget=forms.Textarea(attrs={'rows':2})) + survey = forms.CharField(required = False, widget=forms.Textarea(attrs={'rows':2})) + #survey = forms.CharField(required = False, widget=TinyMCE(attrs={'cols': 80, 'rows': 10})) + kataster_status = forms.CharField(required = False) + underground_centre_line = forms.CharField(required = False, widget=forms.Textarea(attrs={'rows':2})) + notes = forms.CharField(required = False, widget=forms.Textarea(attrs={'rows':2})) + references = forms.CharField(required = False, widget=forms.Textarea(attrs={'rows':1})) + description_file = forms.CharField(required = False, widget=forms.TextInput(attrs={'size': '45'})) + survex_file = forms.CharField(required = False, label="Survex file [caves-1623/000/000.svx]", widget=forms.TextInput(attrs={'size': '45'})) + url = forms.CharField(required = True, label="URL [1623/000/000]", widget=forms.TextInput(attrs={'size': '45'})) + length = forms.CharField(required = False, label="Length (m)") + depth = forms.CharField(required = False, label="Depth (m)") + extent = forms.CharField(required = False, label="Extent (m)") class Meta: model = Cave exclude = ("filename",) - def clean(self): if self.cleaned_data.get("kataster_number") == "" and self.cleaned_data.get("unofficial_number") == "": self._errors["unofficial_number"] = self.error_class(["Either the kataster or unoffical number is required."]) @@ -38,44 +47,57 @@ class CaveForm(ModelForm): if self.cleaned_data.get("area") == []: self._errors["area"] = self.error_class(["This field is required."]) if self.cleaned_data.get("url") and self.cleaned_data.get("url").startswith("/"): - self._errors["url"] = self.error_class(["This field can not start with a /."]) + self._errors["url"] = self.error_class(["This field cannot start with a /."]) return self.cleaned_data class VersionControlCommentForm(forms.Form): - description_of_change = forms.CharField(required = True, widget=forms.Textarea()) + '''Was appended to all forms. Not used currently + ''' + description_of_change = forms.CharField(required = True, widget=forms.Textarea(attrs={'rows':2})) class EntranceForm(ModelForm): - #underground_description = forms.CharField(required = False, widget=TinyMCE(attrs={'cols': 80, 'rows': 30})) + '''Only those fields for which we want to override defaults are listed here + the other fields are present on the form, but use the default presentaiton style + ''' + name = forms.CharField(required = False, widget=forms.TextInput(attrs={'size': '45'})) + entrance_description = forms.CharField(required = False, widget=forms.Textarea(attrs={'rows':9})) + explorers = forms.CharField(required = False, widget=forms.TextInput(attrs={'size': '45'})) #explorers = forms.CharField(required = False, widget=TinyMCE(attrs={'cols': 80, 'rows': 10})) - #equipment = forms.CharField(required = False, widget=TinyMCE(attrs={'cols': 80, 'rows': 10})) - #survey = forms.CharField(required = False, widget=TinyMCE(attrs={'cols': 80, 'rows': 10})) - #kataster_status = forms.CharField(required = False, widget=TinyMCE(attrs={'cols': 80, 'rows': 10})) - #underground_centre_line = forms.CharField(required = False, widget=TinyMCE(attrs={'cols': 80, 'rows': 10})) - #notes = forms.CharField(required = False, widget=TinyMCE(attrs={'cols': 80, 'rows': 10})) - #references = forms.CharField(required = False, widget=TinyMCE(attrs={'cols': 80, 'rows': 10})) - other_station = forms.CharField(required=False) # Trying to change this to a single line entry - tag_station = forms.CharField(required=False) # Trying to change this to a single line entry - exact_station = forms.CharField(required=False) # Trying to change this to a single line entry - northing = forms.CharField(required=False) # Trying to change this to a single line entry - easting = forms.CharField(required=False) # Trying to change this to a single line entry - alt = forms.CharField(required=False) # Trying to change this to a single line entry + map_description = forms.CharField(required = False, widget=forms.Textarea(attrs={'rows':3})) + location_description = forms.CharField(required = False, widget=forms.Textarea(attrs={'rows':3})) + approach = forms.CharField(required = False, widget=forms.Textarea(attrs={'rows':3})) + underground_description = forms.CharField(required = False, widget=forms.Textarea(attrs={'rows':3})) + photo = forms.CharField(required = False, widget=forms.Textarea(attrs={'rows':2})) + marking_comment = forms.CharField(required = False, widget=forms.Textarea(attrs={'rows':2})) + findability_description = forms.CharField(required = False, widget=forms.Textarea(attrs={'rows':2})) + other_description = forms.CharField(required = False, widget=forms.Textarea(attrs={'rows':2})) + bearings = forms.CharField(required = False, widget=forms.Textarea(attrs={'rows':2})) + other_station = forms.CharField(required=False) + tag_station = forms.CharField(required=False) + exact_station = forms.CharField(required=False) + northing = forms.CharField(required=False) + easting = forms.CharField(required=False) + alt = forms.CharField(required=False, label="Altitude (m)") + url = forms.CharField(required = False, label="URL [usually blank]", widget=forms.TextInput(attrs={'size': '45'})) class Meta: model = Entrance exclude = ("cached_primary_slug", "filename",) def clean(self): if self.cleaned_data.get("url").startswith("/"): - self._errors["url"] = self.error_class(["This field can not start with a /."]) + self._errors["url"] = self.error_class(["This field cannot start with a /."]) return self.cleaned_data # This next is called from the templates/edit_cave2.html template. # This is sufficeint to create an entire entry for for the cave fields automatically # http://localhost:8000/cave/new/ -# using django built-in stuff: +# using django built-in Deep magic. https://docs.djangoproject.com/en/2.2/topics/forms/modelforms/ CaveAndEntranceFormSet = modelformset_factory(CaveAndEntrance, exclude=('cave',)) class EntranceLetterForm(ModelForm): + '''Can't see what this does at all + ''' class Meta: model = CaveAndEntrance exclude = ('cave', 'entrance') @@ -120,7 +142,7 @@ def get_name(pe): return pe.person.first_name class UploadFileForm(forms.Form): - """Only called by views.others.newFile() whhich seems to be only about logbook files. + """Only called by views.others.newFile() which seems to be only about logbook files. """ # Because this has EXECUTABLE statements in its signature (the fields) they get # executed when this module is LOADED. Which barfs horribly. diff --git a/core/models/caves.py b/core/models/caves.py index edaae9a..ddb0255 100644 --- a/core/models/caves.py +++ b/core/models/caves.py @@ -182,16 +182,17 @@ class Cave(TroggleModel): def writeDataFile(self): try: - f = open(os.path.join(settings.CAVEDESCRIPTIONS, self.filename), "wb") + f = open(os.path.join(settings.CAVEDESCRIPTIONS, self.filename), "w") except: subprocess.call(settings.FIX_PERMISSIONS) - f = open(os.path.join(settings.CAVEDESCRIPTIONS, self.filename), "wb") + f = open(os.path.join(settings.CAVEDESCRIPTIONS, self.filename), "w") t = loader.get_template('dataformat/cave.xml') #c = Context({'cave': self}) c = dict({'cave': self}) - u = t.render(c) - u8 = u.encode("utf-8") - f.write(u8) + u = t.render(c) + # u8 = u.encode("utf-8") + # f.write(u8) + f.write(u) f.close() def getArea(self): @@ -350,10 +351,11 @@ class Entrance(TroggleModel): subprocess.call(settings.FIX_PERMISSIONS) f = open(os.path.join(settings.ENTRANCEDESCRIPTIONS, self.filename), "w") t = loader.get_template('dataformat/entrance.xml') - c = Context({'entrance': self}) + c = dict({'entrance': self}) u = t.render(c) - u8 = u.encode("utf-8") - f.write(u8) + # u8 = u.encode("utf-8") + # f.write(u8) + f.write(u) f.close() class LogbookEntry(TroggleModel): @@ -641,10 +643,10 @@ def GetCaveLookup(): Gcavelookup["2015-mf-06"] = Gcavelookup["288"] Gcavelookup["2016-jb-01"] = Gcavelookup["289"] Gcavelookup["2017-pw-01"] = Gcavelookup["277"] - Gcavelookup["2018-dm-07"] = Gcavelookup["359"] - Gcavelookup["2017_cucc_24"] = Gcavelookup["291"] # note _ not - here - Gcavelookup["2017_cucc_23"] = Gcavelookup["295"] - Gcavelookup["2017_cucc_28"] = Gcavelookup["290"] + Gcavelookup["2018-dm-07"] = Gcavelookup["359"] # NB this is 1626 + Gcavelookup["2017_cucc_24"] = Gcavelookup["291"] # note _ not - + Gcavelookup["2017_cucc_23"] = Gcavelookup["295"] # note _ not - + Gcavelookup["2017_cucc_28"] = Gcavelookup["290"] # note _ not - Gcavelookup["bs17"] = Gcavelookup["283"] Gcavelookup["1976/b11"] = Gcavelookup["198"] @@ -679,12 +681,14 @@ def GetCaveLookup(): Gcavelookup["gsh"] = Gcavelookup["291"] Gcavelookup["homecoming"] = Gcavelookup["2018-dm-07"] + Gcavelookup["heimkommen"] = Gcavelookup["2018-dm-07"] Gcavelookup["99ob02"] = Gcavelookup["1999-ob-02"] addmore = {} for id in Gcavelookup: addmore[id.replace("-","_")] = Gcavelookup[id] addmore[id.replace("_","-")] = Gcavelookup[id] + addmore[id.upper()] = Gcavelookup[id] Gcavelookup = {**addmore, **Gcavelookup} addmore ={} diff --git a/core/views/caves.py b/core/views/caves.py index c0576c6..a791d80 100644 --- a/core/views/caves.py +++ b/core/views/caves.py @@ -152,7 +152,7 @@ def cave3d(request, cave_id=''): try: cave = getCave(cave_id) except ObjectDoesNotExist: - return None + return HttpResponseNotFound except Cave.MultipleObjectsReturned: # But only one might have survex data? So scan and return the first that works. caves = getCaves(cave_id) @@ -337,7 +337,10 @@ def caveLogbook(request, slug): def edit_cave(request, slug=None): '''This is the form that edits all the cave data and writes out an XML file in the :expoweb: repo folder The format for the file being saved is in templates/dataformat/cave.xml + + It does save the data into into the database directly, not by parsing the file. ''' + message = "" if slug is not None: cave = Cave.objects.get(caveslug__slug = slug) else: @@ -346,7 +349,8 @@ def edit_cave(request, slug=None): form = CaveForm(request.POST, instance=cave) ceFormSet = CaveAndEntranceFormSet(request.POST) versionControlForm = VersionControlCommentForm(request.POST) - if form.is_valid() and ceFormSet.is_valid() and versionControlForm.is_valid(): + if form.is_valid() and ceFormSet.is_valid(): + #print(f'! POST is valid. {cave}') cave = form.save(commit = False) if slug is None: for a in form.cleaned_data["area"]: @@ -367,23 +371,33 @@ def edit_cave(request, slug=None): ceinsts = ceFormSet.save(commit=False) for ceinst in ceinsts: ceinst.cave = cave - ceinst.save() + ceinst.save() cave.writeDataFile() - return HttpResponseRedirect("/" + cave.url) + return HttpResponseRedirect("/" + cave.url) + else: + message = f'! POST data is INVALID {cave}' + print(message) else: form = CaveForm(instance=cave) ceFormSet = CaveAndEntranceFormSet(queryset=cave.caveandentrance_set.all()) - versionControlForm = VersionControlCommentForm() + #versionControlForm = VersionControlCommentForm() return render(request, 'editcave2.html', - {'form': form, + {'form': form, 'cave': cave, 'message': message, 'caveAndEntranceFormSet': ceFormSet, - 'versionControlForm': versionControlForm + #'versionControlForm': versionControlForm }) @login_required_if_public def editEntrance(request, caveslug, slug=None): + '''This is the form that edits the entrance data for a single entrance and writes out + an XML file in the :expoweb: repo folder + The format for the file being saved is in templates/dataformat/entrance.xml + + It does save the data into into the database directly, not by parsing the file. + ''' + message = "" cave = Cave.objects.get(caveslug__slug = caveslug) if slug is not None: entrance = Entrance.objects.get(entranceslug__slug = slug) @@ -391,12 +405,12 @@ def editEntrance(request, caveslug, slug=None): entrance = Entrance() if request.POST: form = EntranceForm(request.POST, instance = entrance) - versionControlForm = VersionControlCommentForm(request.POST) + #versionControlForm = VersionControlCommentForm(request.POST) if slug is None: entletter = EntranceLetterForm(request.POST) else: entletter = None - if form.is_valid() and versionControlForm.is_valid() and (slug is not None or entletter.is_valid()): + if form.is_valid() and (slug is not None or entletter.is_valid()): entrance = form.save(commit = False) if slug is None: slugname = cave.slug() + entletter.cleaned_data["entrance_letter"] @@ -412,17 +426,20 @@ def editEntrance(request, caveslug, slug=None): el.save() entrance.writeDataFile() return HttpResponseRedirect("/" + cave.url) + else: + message = f'! POST data is INVALID {cave}' + print(message) else: form = EntranceForm(instance = entrance) - versionControlForm = VersionControlCommentForm() + #versionControlForm = VersionControlCommentForm() if slug is None: entletter = EntranceLetterForm(request.POST) else: entletter = None return render(request, 'editentrance.html', - {'form': form, - 'versionControlForm': versionControlForm, + {'form': form, 'cave': cave, 'message': message, + #'versionControlForm': versionControlForm, 'entletter': entletter }) diff --git a/templates/editcave2.html b/templates/editcave2.html index 29b9f27..a80a22b 100644 --- a/templates/editcave2.html +++ b/templates/editcave2.html @@ -1,6 +1,5 @@ {% extends "cavebase.html" %} -{% load csrffaker %} -{% block title %}Edit Cave{% endblock %} +{% block title %}Edit Cave - {{cave.official_name|safe}} - {{cave.kataster_number}}{% endblock %} {% block extraheaders %} @@ -9,7 +8,8 @@ {% endblock %} {% block content %} -

Edit Cave

+

Edit Cave - {{cave.official_name|safe}} - {{cave.kataster_number}}

+

{{message}}

{% csrf_token %} {{ form }}{{caveAndEntranceFormSet}}
{{ versionControlForm }} diff --git a/templates/editentrance.html b/templates/editentrance.html index 0b81266..b6befbb 100644 --- a/templates/editentrance.html +++ b/templates/editentrance.html @@ -1,15 +1,18 @@ {% extends "cavebase.html" %} -{% load csrffaker %} + {% block title %}Edit Entrance{% endblock %} {% block extraheaders %} -!----> + {% endblock %} {% block content %} +

Edit Entrance - at cave {{cave.official_name|safe}} - {{cave.kataster_number}}

+

{{message}}

+

{{entletter}} {% csrf_token %} - {{entletter}}{{ form }}
+ {{ form }}
{{ versionControlForm }}