Skip to content

Commit

Permalink
delete removed answers as part of the bulk answer upload
Browse files Browse the repository at this point in the history
If an existing answer is replaced with "-" then the answer in the
database is removed
  • Loading branch information
struan committed Jan 9, 2025
1 parent 5969d61 commit 99edc4d
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 54 deletions.
4 changes: 4 additions & 0 deletions crowdsourcer/tests/data/test_question_upload_one_deleted.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
authority,answer,score,public_notes,page_number,evidence,private_notes
Aberdeen City Council,Yes,1,uploaded public notes,99,uploaded evidence,uploaded private notes
Aberdeenshire Council,-,0,public notrs,0,,private notes
Adur District Council,-,-,-,-,-,-
48 changes: 48 additions & 0 deletions crowdsourcer/tests/test_question_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,3 +123,51 @@ def test_one_new_one_unchanged(self):
self.assertEqual(r.option.description, "Yes")
self.assertEqual(r.page_number, "0")
self.assertEqual(last_update, r.last_update)

def test_one_new_one_deleted(self):
url = reverse("question_bulk_update", args=("Transport", "1"))
response = self.client.get(url)

q = Question.objects.get(
section__title="Transport",
section__marking_session__label="Default",
number=1,
)

all_r = Response.objects.filter(question=q, response_type__type="First Mark")
self.assertEqual(all_r.count(), 1)

exists = Response.objects.filter(
question=q, authority__name="Aberdeenshire Council"
).exists()
self.assertTrue(exists)

upload_file = (
pathlib.Path(__file__).parent.resolve()
/ "data"
/ "test_question_upload_one_deleted.csv"
)

with open(upload_file, "rb") as fp:
response = self.client.post(
url,
data={
"question": 281,
"updated_responses": fp,
"stage": "First Mark",
},
)

self.assertRedirects(response, "/Default" + url)
self.assertEqual(all_r.count(), 1)

r = Response.objects.get(question=q, authority__name="Aberdeen City Council")

self.assertEqual(r.option.description, "Yes")
self.assertEqual(r.page_number, "99")

exists = Response.objects.filter(
question=q, authority__name="Aberdeenshire Council"
).exists()

self.assertFalse(exists)
122 changes: 68 additions & 54 deletions crowdsourcer/views/questions.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,81 +194,95 @@ def form_valid(self, form):
stage = get_object_or_404(ResponseType, type=data["stage"])
is_multi = question.question_type == "multiple_choice"

counts = {"updated": 0, "added": 0, "deleted": 0}
with transaction.atomic():
for index, row in form.responses_df.iterrows():
answer = row["answer"].strip()
if answer == "-":
continue

if is_multi:
answers = answer.split("|")

authority = PublicAuthority.objects.get(
name=row["authority"],
marking_session=self.request.current_session,
)
if not is_multi:
option = Option.objects.get(question=question, description=answer)

if answer != "-":
if is_multi:
answers = answer.split("|")

if not is_multi:
option = Option.objects.get(
question=question, description=answer
)

try:
response = Response.objects.get(
question=question, response_type=stage, authority=authority
)
changed = False
opts = {}
for col in [
"page_number",
"evidence",
"public_notes",
"private_notes",
]:
val = row[col]
if pd.isna(val):
val = None
if col == "private_notes":
val = ""
if val != getattr(response, col):
opts[col] = val
if answer == "-":
response.delete()
counts["deleted"] += 1
else:
changed = False
opts = {}
for col in [
"page_number",
"evidence",
"public_notes",
"private_notes",
]:
val = row[col]
if pd.isna(val):
val = None
if col == "private_notes":
val = ""
if val != getattr(response, col):
opts[col] = val
changed = True
if not is_multi and response.option != option:
changed = True
if not is_multi and response.option != option:
changed = True
opts["option"] = option
opts["option"] = option

if changed:
counts["updated"] += 1
response.user = self.request.user
for k, v in opts.items():
setattr(response, k, v)
response.save()

if is_multi:
response.multi_option.clear()
for a in answers:
option = Option.objects.get(
question=question, description=a
)
response.multi_option.add(option.id)

if changed:
response.user = self.request.user
for k, v in opts.items():
setattr(response, k, v)
response.save()
except Response.DoesNotExist:
if answer != "-":
counts["added"] += 1
opts = {
"question": question,
"response_type": stage,
"authority": authority,
"user": self.request.user,
}
for col in ["page_number", "evidence", "public_notes"]:
if pd.isna(row[col]) is False:
opts[col] = row[col]
if not is_multi:
opts["option"] = option

response = Response.objects.create(**opts)

if is_multi:
response.multi_option.clear()
for a in answers:
option = Option.objects.get(
question=question, description=a
)
response.multi_option.add(option.id)

except Response.DoesNotExist:
opts = {
"question": question,
"response_type": stage,
"authority": authority,
"user": self.request.user,
}
for col in ["page_number", "evidence", "public_notes"]:
if pd.isna(row[col]) is False:
opts[col] = row[col]
if not is_multi:
opts["option"] = option

response = Response.objects.create(**opts)

if is_multi:
for a in answers:
option = Option.objects.get(
question=question, description=a
)
response.multi_option.add(option.id)

messages.add_message(self.request, messages.SUCCESS, "Question updated!")
messages.add_message(
self.request,
messages.INFO,
f"{counts['updated']} updated, {counts['added']} added, {counts['deleted']} deleted",
)
return super().form_valid(form)

0 comments on commit 99edc4d

Please sign in to comment.