Skip to content

Commit 0a1c2aa

Browse files
committed
delete removed answers as part of the bulk answer upload
If an existing answer is replaced with "-" then the answer in the database is removed
1 parent 5969d61 commit 0a1c2aa

File tree

2 files changed

+116
-54
lines changed

2 files changed

+116
-54
lines changed

crowdsourcer/tests/test_question_views.py

+48
Original file line numberDiff line numberDiff line change
@@ -123,3 +123,51 @@ def test_one_new_one_unchanged(self):
123123
self.assertEqual(r.option.description, "Yes")
124124
self.assertEqual(r.page_number, "0")
125125
self.assertEqual(last_update, r.last_update)
126+
127+
def test_one_new_one_deleted(self):
128+
url = reverse("question_bulk_update", args=("Transport", "1"))
129+
response = self.client.get(url)
130+
131+
q = Question.objects.get(
132+
section__title="Transport",
133+
section__marking_session__label="Default",
134+
number=1,
135+
)
136+
137+
all_r = Response.objects.filter(question=q, response_type__type="First Mark")
138+
self.assertEqual(all_r.count(), 1)
139+
140+
exists = Response.objects.filter(
141+
question=q, authority__name="Aberdeenshire Council"
142+
).exists()
143+
self.assertTrue(exists)
144+
145+
upload_file = (
146+
pathlib.Path(__file__).parent.resolve()
147+
/ "data"
148+
/ "test_question_upload_one_deleted.csv"
149+
)
150+
151+
with open(upload_file, "rb") as fp:
152+
response = self.client.post(
153+
url,
154+
data={
155+
"question": 281,
156+
"updated_responses": fp,
157+
"stage": "First Mark",
158+
},
159+
)
160+
161+
self.assertRedirects(response, "/Default" + url)
162+
self.assertEqual(all_r.count(), 1)
163+
164+
r = Response.objects.get(question=q, authority__name="Aberdeen City Council")
165+
166+
self.assertEqual(r.option.description, "Yes")
167+
self.assertEqual(r.page_number, "99")
168+
169+
exists = Response.objects.filter(
170+
question=q, authority__name="Aberdeenshire Council"
171+
).exists()
172+
173+
self.assertFalse(exists)

crowdsourcer/views/questions.py

+68-54
Original file line numberDiff line numberDiff line change
@@ -194,81 +194,95 @@ def form_valid(self, form):
194194
stage = get_object_or_404(ResponseType, type=data["stage"])
195195
is_multi = question.question_type == "multiple_choice"
196196

197+
counts = {"updated": 0, "added": 0, "deleted": 0}
197198
with transaction.atomic():
198199
for index, row in form.responses_df.iterrows():
199200
answer = row["answer"].strip()
200-
if answer == "-":
201-
continue
202-
203-
if is_multi:
204-
answers = answer.split("|")
205-
206201
authority = PublicAuthority.objects.get(
207202
name=row["authority"],
208203
marking_session=self.request.current_session,
209204
)
210-
if not is_multi:
211-
option = Option.objects.get(question=question, description=answer)
205+
206+
if answer != "-":
207+
if is_multi:
208+
answers = answer.split("|")
209+
210+
if not is_multi:
211+
option = Option.objects.get(
212+
question=question, description=answer
213+
)
212214

213215
try:
214216
response = Response.objects.get(
215217
question=question, response_type=stage, authority=authority
216218
)
217-
changed = False
218-
opts = {}
219-
for col in [
220-
"page_number",
221-
"evidence",
222-
"public_notes",
223-
"private_notes",
224-
]:
225-
val = row[col]
226-
if pd.isna(val):
227-
val = None
228-
if col == "private_notes":
229-
val = ""
230-
if val != getattr(response, col):
231-
opts[col] = val
219+
if answer == "-":
220+
response.delete()
221+
counts["deleted"] += 1
222+
else:
223+
changed = False
224+
opts = {}
225+
for col in [
226+
"page_number",
227+
"evidence",
228+
"public_notes",
229+
"private_notes",
230+
]:
231+
val = row[col]
232+
if pd.isna(val):
233+
val = None
234+
if col == "private_notes":
235+
val = ""
236+
if val != getattr(response, col):
237+
opts[col] = val
238+
changed = True
239+
if not is_multi and response.option != option:
232240
changed = True
233-
if not is_multi and response.option != option:
234-
changed = True
235-
opts["option"] = option
241+
opts["option"] = option
242+
243+
if changed:
244+
counts["updated"] += 1
245+
response.user = self.request.user
246+
for k, v in opts.items():
247+
setattr(response, k, v)
248+
response.save()
249+
250+
if is_multi:
251+
response.multi_option.clear()
252+
for a in answers:
253+
option = Option.objects.get(
254+
question=question, description=a
255+
)
256+
response.multi_option.add(option.id)
236257

237-
if changed:
238-
response.user = self.request.user
239-
for k, v in opts.items():
240-
setattr(response, k, v)
241-
response.save()
258+
except Response.DoesNotExist:
259+
if answer != "-":
260+
counts["added"] += 1
261+
opts = {
262+
"question": question,
263+
"response_type": stage,
264+
"authority": authority,
265+
"user": self.request.user,
266+
}
267+
for col in ["page_number", "evidence", "public_notes"]:
268+
if pd.isna(row[col]) is False:
269+
opts[col] = row[col]
270+
if not is_multi:
271+
opts["option"] = option
272+
273+
response = Response.objects.create(**opts)
242274

243275
if is_multi:
244-
response.multi_option.clear()
245276
for a in answers:
246277
option = Option.objects.get(
247278
question=question, description=a
248279
)
249280
response.multi_option.add(option.id)
250281

251-
except Response.DoesNotExist:
252-
opts = {
253-
"question": question,
254-
"response_type": stage,
255-
"authority": authority,
256-
"user": self.request.user,
257-
}
258-
for col in ["page_number", "evidence", "public_notes"]:
259-
if pd.isna(row[col]) is False:
260-
opts[col] = row[col]
261-
if not is_multi:
262-
opts["option"] = option
263-
264-
response = Response.objects.create(**opts)
265-
266-
if is_multi:
267-
for a in answers:
268-
option = Option.objects.get(
269-
question=question, description=a
270-
)
271-
response.multi_option.add(option.id)
272-
273282
messages.add_message(self.request, messages.SUCCESS, "Question updated!")
283+
messages.add_message(
284+
self.request,
285+
messages.INFO,
286+
f"{counts['updated']} updated, {counts['added']} added, {counts['deleted']} deleted",
287+
)
274288
return super().form_valid(form)

0 commit comments

Comments
 (0)