This commit is contained in:
David Kennedy 2024-01-03 12:40:05 -05:00
parent 2894421a5a
commit 08dcdb85cd
No known key found for this signature in database
GPG key ID: 6528A5386E66B96B
3 changed files with 48 additions and 104 deletions

View file

@ -126,6 +126,9 @@ class RegistrarFormSet(forms.BaseFormSet):
for db_obj, post_data in zip_longest(query, self.forms, fillvalue=None): for db_obj, post_data in zip_longest(query, self.forms, fillvalue=None):
cleaned = post_data.cleaned_data if post_data is not None else {} cleaned = post_data.cleaned_data if post_data is not None else {}
logger.info(f"in _to_database for {self.__class__.__name__}")
logger.info(db_obj)
logger.info(cleaned)
# matching database object exists, update it # matching database object exists, update it
if db_obj is not None and cleaned: if db_obj is not None and cleaned:
if should_delete(cleaned): if should_delete(cleaned):
@ -136,7 +139,7 @@ class RegistrarFormSet(forms.BaseFormSet):
db_obj.save() db_obj.save()
# no matching database object, create it # no matching database object, create it
elif db_obj is None and cleaned: elif db_obj is None and cleaned and not cleaned.get('delete', False):
kwargs = pre_create(db_obj, cleaned) kwargs = pre_create(db_obj, cleaned)
getattr(obj, join).create(**kwargs) getattr(obj, join).create(**kwargs)
@ -601,7 +604,7 @@ class OtherContactsForm(RegistrarForm):
def mark_form_for_deletion(self): def mark_form_for_deletion(self):
logger.info("removing form data from other contact") logger.info("removing form data from other contact")
self.data = {} # self.data = {}
self.form_data_marked_for_deletion = True self.form_data_marked_for_deletion = True
def clean(self): def clean(self):
@ -615,25 +618,26 @@ class OtherContactsForm(RegistrarForm):
if self.form_data_marked_for_deletion: if self.form_data_marked_for_deletion:
# Set form_is_empty to True initially # Set form_is_empty to True initially
form_is_empty = True # form_is_empty = True
for name, field in self.fields.items(): # for name, field in self.fields.items():
# get the value of the field from the widget # # get the value of the field from the widget
value = field.widget.value_from_datadict(self.data, self.files, self.add_prefix(name)) # value = field.widget.value_from_datadict(self.data, self.files, self.add_prefix(name))
# if any field in the submitted form is not empty, set form_is_empty to False # # if any field in the submitted form is not empty, set form_is_empty to False
if value is not None and value != "": # if value is not None and value != "":
form_is_empty = False # form_is_empty = False
if form_is_empty: # if form_is_empty:
# clear any errors raised by the form fields # # clear any errors raised by the form fields
# (before this clean() method is run, each field # # (before this clean() method is run, each field
# performs its own clean, which could result in # # performs its own clean, which could result in
# errors that we wish to ignore at this point) # # errors that we wish to ignore at this point)
# # #
# NOTE: we cannot just clear() the errors list. # # NOTE: we cannot just clear() the errors list.
# That causes problems. # # That causes problems.
for field in self.fields: for field in self.fields:
if field in self.errors: if field in self.errors:
del self.errors[field] del self.errors[field]
return {'delete': True}
return self.cleaned_data return self.cleaned_data
@ -650,9 +654,16 @@ class BaseOtherContactsFormSet(RegistrarFormSet):
self.formset_data_marked_for_deletion = False self.formset_data_marked_for_deletion = False
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
def pre_update(self, db_obj, cleaned):
"""Code to run before an item in the formset is saved."""
for key, value in cleaned.items():
setattr(db_obj, key, value)
def should_delete(self, cleaned): def should_delete(self, cleaned):
empty = (isinstance(v, str) and (v.strip() == "" or v is None) for v in cleaned.values()) empty = (isinstance(v, str) and (v.strip() == "" or v is None) for v in cleaned.values())
return all(empty) logger.info(f"should_delete => {all(empty)}")
return all(empty) or self.formset_data_marked_for_deletion
def to_database(self, obj: DomainApplication): def to_database(self, obj: DomainApplication):
logger.info("to_database called on BaseOtherContactsFormSet") logger.info("to_database called on BaseOtherContactsFormSet")
@ -686,6 +697,7 @@ OtherContactsFormSet = forms.formset_factory(
absolute_max=1500, # django default; use `max_num` to limit entries absolute_max=1500, # django default; use `max_num` to limit entries
min_num=1, min_num=1,
validate_min=True, validate_min=True,
# can_delete=True,
formset=BaseOtherContactsFormSet, formset=BaseOtherContactsFormSet,
) )

View file

@ -29,6 +29,10 @@
<h2>Organization contact {{ forloop.counter }} (optional)</h2> <h2>Organization contact {{ forloop.counter }} (optional)</h2>
</legend> </legend>
{% if forms.1.can_delete %}
{{ form.DELETE }}
{% endif %}
{% input_with_errors form.first_name %} {% input_with_errors form.first_name %}
{% input_with_errors form.middle_name %} {% input_with_errors form.middle_name %}

View file

@ -1,6 +1,6 @@
import logging import logging
from django.http import Http404, HttpResponse, HttpResponseRedirect from django.http import Http404, HttpResponse, HttpResponseRedirect, QueryDict
from django.shortcuts import redirect, render from django.shortcuts import redirect, render
from django.urls import resolve, reverse from django.urls import resolve, reverse
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
@ -412,6 +412,7 @@ class ApplicationWizard(ApplicationWizardPermissionView, TemplateView):
""" """
for form in forms: for form in forms:
if form is not None and hasattr(form, "to_database"): if form is not None and hasattr(form, "to_database"):
logger.info(f"saving form {form.__class__.__name__}")
form.to_database(self.application) form.to_database(self.application)
@ -486,87 +487,6 @@ class OtherContacts(ApplicationWizard):
template_name = "application_other_contacts.html" template_name = "application_other_contacts.html"
forms = [forms.OtherContactsYesNoForm, forms.OtherContactsFormSet, forms.NoOtherContactsForm] forms = [forms.OtherContactsYesNoForm, forms.OtherContactsFormSet, forms.NoOtherContactsForm]
# def post(self, request, *args, **kwargs) -> HttpResponse:
# """This method handles POST requests."""
# # Log the keys and values of request.POST
# for key, value in request.POST.items():
# logger.info("Key: %s, Value: %s", key, value)
# # if accessing this class directly, redirect to the first step
# if self.__class__ == ApplicationWizard:
# return self.goto(self.steps.first)
# # which button did the user press?
# button: str = request.POST.get("submit_button", "")
# forms = self.get_forms(use_post=True)
# # forms is now set as follows:
# # forms.0 is yes no form
# # forms.1 - forms.length-1 are other contacts forms
# # forms.length is no other contacts form
# yes_no_form = forms[0]
# other_contacts_forms = forms[1]
# no_other_contacts_form = forms[2]
# all_forms_valid = True
# # test first for yes_no_form validity
# if yes_no_form.is_valid():
# logger.info("yes no form is valid")
# # test for has_contacts
# if yes_no_form.cleaned_data.get('has_other_contacts'):
# logger.info("has other contacts")
# # remove data from no_other_contacts_form and set
# # form to always_valid
# no_other_contacts_form.remove_form_data()
# # test that the other_contacts_forms and no_other_contacts_forms are valid
# if not self.is_valid(forms[1:]):
# all_forms_valid = False
# else:
# logger.info("has no other contacts")
# # remove data from each other_contacts_form
# other_contacts_forms.remove_form_data()
# # test that the other_contacts_forms and no_other_contacts_forms are valid
# if not self.is_valid(forms[1:]):
# all_forms_valid = False
# else:
# all_forms_valid = False
# if all_forms_valid:
# logger.info("all forms are valid")
# # always save progress
# self.save(forms)
# else:
# context = self.get_context_data()
# context["forms"] = forms
# return render(request, self.template_name, context)
# # if user opted to save their progress,
# # return them to the page they were already on
# if button == "save":
# messages.success(request, "Your progress has been saved!")
# return self.goto(self.steps.current)
# # if user opted to save progress and return,
# # return them to the home page
# if button == "save_and_return":
# return HttpResponseRedirect(reverse("home"))
# # otherwise, proceed as normal
# return self.goto_next_step()
# def post(self, request, *args, **kwargs) -> HttpResponse:
# parent_form = forms.OtherContactsYesNoForm(request.POST, **kwargs)
# other_contacts_formset = forms.OtherContactsFormSet(request.POST, **kwargs)
# no_other_contacts_form = forms.NoOtherContactsForm(request.POST, **kwargs)
# logger.info("in post")
# has_other_contacts_selected = parent_form.data.get('other_contacts-has_other_contacts')
# logger.info(f"has other contacts = {has_other_contacts_selected}")
# if has_other_contacts_selected:
# logger.info("has other contacts")
# other_contacts_formset.data = {}
# else:
# logger.info("doesn't have other contacts")
# no_other_contacts_form.data = {}
# return super().post(request, *args, **kwargs)
def is_valid(self, forms: list) -> bool: def is_valid(self, forms: list) -> bool:
"""Overrides default behavior defined in ApplicationWizard. """Overrides default behavior defined in ApplicationWizard.
Depending on value in other_contacts_yes_no_form, marks forms in Depending on value in other_contacts_yes_no_form, marks forms in
@ -593,7 +513,15 @@ class OtherContacts(ApplicationWizard):
logger.info("has no other contacts") logger.info("has no other contacts")
# remove data from each other_contacts_form # remove data from each other_contacts_form
other_contacts_forms.mark_formset_for_deletion() other_contacts_forms.mark_formset_for_deletion()
# test that the other_contacts_forms and no_other_contacts_forms are valid # set the delete data to on in each form
# Create a mutable copy of the QueryDict
# mutable_data = QueryDict(mutable=True)
# mutable_data.update(self.request.POST.copy())
# for i, form in enumerate(other_contacts_forms.forms):
# form_prefix = f'other_contacts-{i}'
# mutable_data[f'{form_prefix}-deleted'] = 'on'
# other_contacts_forms.forms[i].data = mutable_data.copy()
all_forms_valid = all(form.is_valid() for form in forms[1:]) all_forms_valid = all(form.is_valid() for form in forms[1:])
else: else:
all_forms_valid = False all_forms_valid = False