Bases: BaseStreamForm
, UpdateView
wagtail_reference_index_ignore
class-attribute
instance-attribute
wagtail_reference_index_ignore = True
model
class-attribute
instance-attribute
object
class-attribute
instance-attribute
from_db
classmethod
from_db(db, field_names, values)
Source code in hypha/apply/stream_forms/models.py
| @classmethod
def from_db(cls, db, field_names, values):
instance = super().from_db(db, field_names, values)
if "form_data" in field_names:
instance.form_data = cls.deserialize_form_data(
instance, instance.form_data, instance.form_fields
)
return instance
|
deserialize_form_data(instance, form_data, form_fields)
Source code in hypha/apply/stream_forms/models.py
| @classmethod
def deserialize_form_data(cls, instance, form_data, form_fields):
data = form_data.copy()
# PERFORMANCE NOTE:
# Do not attempt to iterate over form_fields - that will fully instantiate the form_fields
# including any sub queries that they do
for _i, field_data in enumerate(form_fields.raw_data):
block = form_fields.stream_block.child_blocks[field_data["type"]]
field_id = field_data.get("id")
try:
value = data[field_id]
except KeyError:
pass
else:
data[field_id] = block.decode(value)
return data
|
get_defined_fields
Source code in hypha/apply/stream_forms/models.py
| def get_defined_fields(self):
return self.form_fields
|
get_form_fields(draft=False, form_data=None, user=None)
Source code in hypha/apply/stream_forms/models.py
| def get_form_fields(self, draft=False, form_data=None, user=None):
if form_data is None:
form_data = {}
form_fields = OrderedDict()
field_blocks = self.get_defined_fields()
group_counter = 1
is_in_group = False
# If true option 1 is selected
grouped_fields_visible = False
for struct_child in field_blocks:
block = struct_child.block
struct_value = struct_child.value
if isinstance(block, FormFieldBlock):
field_from_block = block.get_field(struct_value)
disabled_help_text = _(
"You are logged in so this information is fetched from your user account."
)
if isinstance(block, FullNameBlock) and user and user.is_authenticated:
if user.full_name:
field_from_block.disabled = True
field_from_block.initial = user.full_name
field_from_block.help_text = disabled_help_text
else:
field_from_block.help_text = _(
"You are logged in but your user account does not have a "
"full name. We'll update your user account with the name you provide here."
)
if isinstance(block, EmailBlock) and user and user.is_authenticated:
field_from_block.disabled = True
field_from_block.initial = user.email
field_from_block.help_text = disabled_help_text
if draft and not issubclass(
block.__class__, ApplicationMustIncludeFieldBlock
):
field_from_block.required = False
field_from_block.help_link = struct_value.get("help_link")
field_from_block.group_number = group_counter if is_in_group else 1
if isinstance(block, GroupToggleBlock) and not is_in_group:
field_from_block.group_number = 1
field_from_block.grouper_for = group_counter + 1
group_counter += 1
is_in_group = True
grouped_fields_visible = (
form_data.get(struct_child.id) == field_from_block.choices[0][0]
)
if isinstance(block, TextFieldBlock):
field_from_block.word_limit = struct_value.get("word_limit")
if isinstance(block, MultiInputCharFieldBlock):
number_of_inputs = struct_value.get("number_of_inputs")
for index in range(number_of_inputs):
form_fields[struct_child.id + "_" + str(index)] = (
field_from_block
)
field_from_block.multi_input_id = struct_child.id
field_from_block.add_button_text = struct_value.get(
"add_button_text"
)
if (
index == number_of_inputs - 1
): # Add button after last input field
field_from_block.multi_input_add_button = True
# Index for field until which fields will be visible to applicant.
# Initially only the first field with id UUID_0 will be visible.
field_from_block.visibility_index = 0
field_from_block.max_index = index
if index != 0:
field_from_block.multi_input_field = True
field_from_block.required = False
field_from_block.initial = None
field_from_block = copy.copy(field_from_block)
else:
if is_in_group and not isinstance(block, GroupToggleBlock):
field_from_block.required_when_visible = (
field_from_block.required
)
field_from_block.required = (
field_from_block.required & grouped_fields_visible
)
field_from_block.visible = grouped_fields_visible
form_fields[struct_child.id] = field_from_block
elif isinstance(block, GroupToggleEndBlock):
# Group toggle end block is used only to group fields and not used in actual form.
# Todo: Use streamblock to create nested form field blocks, a more elegant method to group form fields.
is_in_group = False
else:
field_wrapper = BlockFieldWrapper(struct_child)
field_wrapper.group_number = group_counter if is_in_group else 1
form_fields[struct_child.id] = field_wrapper
return form_fields
|
get_form_class(draft=False, form_data=None, user=None)
Expects self.form_fields to have already been set.
Source code in hypha/apply/projects/views/report.py
| def get_form_class(self, draft=False, form_data=None, user=None):
"""
Expects self.form_fields to have already been set.
"""
# This is where the magic happens.
fields = self.get_form_fields(draft, form_data, user)
the_class = type(
"WagtailStreamForm",
(ReportEditForm,),
fields,
)
return the_class
|
dispatch
dispatch(request, *args, **kwargs)
Source code in hypha/apply/projects/views/report.py
| def dispatch(self, request, *args, **kwargs):
report = self.get_object()
permission, _ = has_permission(
"report_update", self.request.user, object=report, raise_exception=True
)
self.object = report
# super().dispatch calls get_context_data() which calls the rest to get the form fully ready for use.
return super().dispatch(request, *args, **kwargs)
|
get_context_data
get_context_data(*args, **kwargs)
Django note: super().dispatch calls get_context_data.
Source code in hypha/apply/projects/views/report.py
| def get_context_data(self, *args, **kwargs):
"""
Django note: super().dispatch calls get_context_data.
"""
# Is this where we need to get the associated form fields? Not in the form itself but up here? Yes. But in a
# roundabout way: get_form (here) gets fields and calls get_form_class (here) which calls get_form_fields
# (super) which sets up the fields in the returned form.
form = self.get_form()
context_data = {
"form": form,
"object": self.object,
"report_form": True
if self.object.project.submission.page.specific.report_forms.first()
else False,
**kwargs,
}
return context_data
|
get_form(form_class=None)
Source code in hypha/apply/projects/views/report.py
| def get_form(self, form_class=None):
if self.object.current is None or self.object.current.form_fields is None:
# Here is where we get the form_fields, the ProjectReportForm associated with the Fund:
report_form = (
self.object.project.submission.page.specific.report_forms.first()
)
if report_form:
self.form_fields = report_form.form.form_fields
else:
self.form_fields = {}
else:
self.form_fields = self.object.current.form_fields
if form_class is None:
form_class = self.get_form_class()
report_instance = form_class(**self.get_form_kwargs())
return report_instance
|
get_initial
Source code in hypha/apply/projects/views/report.py
| def get_initial(self):
initial = {}
if self.object.draft:
current = self.object.draft
else:
current = self.object.current
# current here is a ReportVersion which should already have the data associated.
if current:
# The following allows existing data to populate the form. This code was inspired by (aka copied from)
# ProjectFormEditView.get_paf_form_kwargs().
initial = current.raw_data
# Is the following needed to see the file in a friendly URL? Does not appear so. But needed to not blow up.
for field_id in current.file_field_ids:
initial.pop(field_id + "-uploads", False)
initial[field_id] = get_placeholder_file(current.raw_data.get(field_id))
return initial
|
Source code in hypha/apply/projects/views/report.py
| def get_form_kwargs(self):
form_kwargs = {
"user": self.request.user,
**super().get_form_kwargs(),
}
return form_kwargs
|
post
post(request, *args, **kwargs)
Source code in hypha/apply/projects/views/report.py
| def post(self, request, *args, **kwargs):
form = self.get_form()
if form.is_valid():
form.save(form_fields=self.form_fields)
form.delete_temporary_files()
response = HttpResponseRedirect(self.get_success_url())
else:
response = self.form_invalid(form)
return response
|
get_success_url
Source code in hypha/apply/projects/views/report.py
| def get_success_url(self):
success_url = self.object.project.get_absolute_url()
return success_url
|
Source code in hypha/apply/projects/views/report.py
| def form_valid(self, form):
response = super().form_valid(form)
should_notify = True
if self.object.draft:
# It was a draft submission
should_notify = False
else:
if self.object.submitted != self.object.current.submitted:
# It was a staff edit - post submission
should_notify = False
if should_notify:
messenger(
MESSAGES.SUBMIT_REPORT,
request=self.request,
user=self.request.user,
source=self.object.project,
related=self.object,
)
# Required for django-file-form: delete temporary files for the new files
# that are uploaded.
form.delete_temporary_files()
return response
|