Commits

Branko Vukelic committed 4872415

Return 410 on POST and 404 on GET getting related

See ticket #1.

  • Participants
  • Parent commits a4bbd33

Comments (0)

Files changed (2)

File related/views.py

 from django.core.exceptions import ImproperlyConfigured
-from django.http import HttpResponseRedirect, Http404
+from django.http import HttpResponseRedirect, HttpResponseGone, Http404
 from django.contrib import messages
 from django.db import IntegrityError
 
     related_pk_url_kwarg = 'pk'
     related_slug_field = 'slug'
     related_slug_url_kwarg = 'slug'
+    related_object_gone_message = '<h2>Database record is missing</h2>'
     integrity_error_message = 'Such record already exists'
 
     def get_related_404_url(self):
         if related_404_url:
             return HttpResponseRedirect(related_404_url)
         else:
-            raise Http404()
+            if self.request.method in ('GET', 'HEAD'):
+                raise Http404()
+            else:
+                # We assume that, if user was able to GET this response,
+                # and is now sending a POST via a form, the object must
+                # have gone AWOL in between. So we do a 410 (Gone).
+                self.related_object_gone()
+
+    def get_related_object_gone_message(self):
+        return self.related_object_gone_message
+
+    def related_object_gone(self):
+        return self.render_to_response(
+            HttpResponseGone(self.get_related_object_gone_message())
+        )
 
     def form_valid(self, form):
         try:

File tests/tests.py

     def test_related_object_not_found(self):
         from django.http import Http404, HttpResponseRedirect
 
+        self.view.request.method = 'GET'
+
         self.view.related_404_redirect_url = '/foo'
         response = self.view.related_object_not_found()
         self.assertIsInstance(response, HttpResponseRedirect)
         with self.assertRaises(Http404):
             self.view.related_object_not_found()
 
+    def test_related_object_gone(self):
+        self.view.request.method = 'POST'
+        self.view.related_object_gone = Mock()
+        self.view.related_object_not_found()
+        self.view.related_object_gone.assert_called_once()
+
     def test_context(self):
         class Super(object):
             def get_context_data(self):