Newer
Older
from django.utils.text import mark_safe
from opentech.apply.stream_forms.blocks import FormFieldBlock
from opentech.apply.utils.blocks import MustIncludeFieldBlock
from opentech.apply.stream_forms.blocks import UploadableMediaBlock
from opentech.apply.stream_forms.files import StreamFieldFile
__all__ = ['AccessFormData']
class AccessFormData:
"""Mixin for interacting with form data from streamfields
requires:
- form_data > jsonfield containing the submitted data
- form_fields > streamfield containing the original form fields
"""
@property
def raw_data(self):
# Returns the data mapped by field id instead of the data stored using the must include
# values
data = self.form_data.copy()
for field_name, field_id in self.must_include.items():
if field_id not in data:
response = data[field_name]
data[field_id] = response
@property
def deserialised_data(self):
# Converts the file dicts into actual file objects
data = self.raw_data.copy()
for field in self.form_fields:
if isinstance(field.block, UploadableMediaBlock):
file = data.get(field.id, [])
try:
data[field.id] = StreamFieldFile(file.file, name=file.name)
except AttributeError:
data[field.id] = [StreamFieldFile(f.file, name=f.name) for f in file]
return data
def get_definitive_id(self, id):
if id in self.must_include:
return self.must_include[id]
return id
def field(self, id):
definitive_id = self.get_definitive_id(id)
return self.raw_fields[definitive_id]
def data(self, id):
definitive_id = self.get_definitive_id(id)
return self.deserialised_data[definitive_id]
except KeyError as e:
# We have most likely progressed application forms so the data isnt in form_data
return None
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
@property
def question_field_ids(self):
for field_id, field in self.fields.items():
if isinstance(field.block, FormFieldBlock):
yield field_id
@property
def raw_fields(self):
# Field ids to field class mapping - similar to raw_data
return {
field.id: field
for field in self.form_fields
}
@property
def fields(self):
# ALl fields on the application
fields = self.raw_fields.copy()
for field_name, field_id in self.must_include.items():
response = fields.pop(field_id)
fields[field_name] = response
return fields
@property
def must_include(self):
return {
field.block.name: field.id
for field in self.form_fields
if isinstance(field.block, MustIncludeFieldBlock)
}
def render_answer(self, field_id, include_question=False):
field = self.field(field_id)
data = self.data(field_id)
return field.render(context={'data': data, 'include_question': include_question})
def render_answers(self):
# Returns a list of the rendered answers
return [
self.render_answer(field_id, include_question=True)
for field_id in self.question_field_ids
if field_id not in self.must_include
]
def output_answers(self):
# Returns a safe string of the rendered answers
return mark_safe(''.join(self.render_answers()))