From 20fefb9208fadc48a25277ce2328793edf978678 Mon Sep 17 00:00:00 2001 From: Armin Samii Date: Sun, 1 Nov 2026 15:46:55 -0500 Subject: [PATCH] handle deletion stale cache for homepage and electionpage --- templates/visualizer/confirmDeleteUpload.html | 5 +++++ visualizer/tests/testUserDashboard.py | 3 +++ visualizer/views.py | 10 ++++++++++ 3 files changed, 18 insertions(+) diff --git a/templates/visualizer/confirmDeleteUpload.html b/templates/visualizer/confirmDeleteUpload.html index dd831713..fc9fd073 100644 --- a/templates/visualizer/confirmDeleteUpload.html +++ b/templates/visualizer/confirmDeleteUpload.html @@ -23,6 +23,11 @@

Delete this visualization?

Note: this visualization is updated automatically from an official data source. Deleting it will stop those updates.

{% endif %} + {% if isOnElectionPage %} +

+ Note: this visualization appears on an election results page. Deleting it will remove it from that page. +

+ {% endif %}
{% csrf_token %} diff --git a/visualizer/tests/testUserDashboard.py b/visualizer/tests/testUserDashboard.py index 2140e845..b4160fd4 100644 --- a/visualizer/tests/testUserDashboard.py +++ b/visualizer/tests/testUserDashboard.py @@ -161,3 +161,6 @@ def test_delete(self): self.assertEqual(response.url, reverse('userDashboard')) self.assertFalse(JsonConfig.objects.filter(pk=config.pk).exists()) mockCloudflare.purge_vis_cache.assert_called_once_with(config.slug) + # The homepage recent list and the sitemap linked to it, too + mockCloudflare.purge_paths_cache.assert_called_once_with( + ['/', '/index.html', '/sitemap.xml']) diff --git a/visualizer/views.py b/visualizer/views.py index 44e04f22..53222cec 100644 --- a/visualizer/views.py +++ b/visualizer/views.py @@ -35,6 +35,7 @@ from accounts.permissions import IsOwnerOrReadOnly, HasAPIAccess from common import viewUtils from common.cloudflare import CloudflareAPI +from electionpage.models import ElectionPage from scraper.models import Scraper, MultiScraper from visualizer import validators from visualizer.common import make_complete_url, intify @@ -215,14 +216,23 @@ def get_context_data(self, **kwargs): jsonConfig=self.object).exists() context['hasScraper'] = Scraper.objects.filter(jsonConfig=self.object).exists() or \ MultiScraper.objects.filter(jsonConfig=self.object).exists() + context['isOnElectionPage'] = ElectionPage.objects.filter( + listOfElections=self.object).exists() return context def form_valid(self, form): # Cloudflare purging only happens in JsonConfig.save() - on deletion, # we must purge here to avoid serving cached copies of a deleted page slug = self.object.slug + electionPagePaths = [ + reverse('electionPage', args=(page.slug,)) + for page in ElectionPage.objects.filter(listOfElections=self.object)] response = super().form_valid(form) CloudflareAPI.purge_vis_cache(slug) + # The homepage's recent list, the sitemap, and any election pages that + # included this visualization would otherwise keep linking to it + CloudflareAPI.purge_paths_cache( + ['/', '/index.html', '/sitemap.xml'] + electionPagePaths) return response