Repository: django-cms/django-cms

Issue:
Location changes after saving a model, why?
Once I "Save" after editing a model in the sideframe, the location of the main page changes to that object's get_absolute_url(). I suspect someone put this in as a feature, but its not what the operator expects to happen and is a nuisance, in my case, probably others’. Is this how its always been? Seems new to me.
##### A (real) use case to illustrate:

I have a model that defines a lot of images and their meta-data for a photography site. These images can be displayed in their own right (and therefore have a method get_absolute_url()), but are also part of different collections/sets. Also, these images are used in plugins throughout the site and even on the blog posts.

So, I notice while looking at a random CMS page that I am working on that a particular image's meta-data needs editing, so while I'm on that random page, I edit the meta data in the sideframe for that image. Once I press save, boom, my context is gone. And, in fact, if I was in the middle of a page edit, I could even lose work.



Discussion:
Ok, delete the previous comment
Issue confirmed.
Looks related to the changes in #2665 
Once `cms_log_latest` session property is set, `PageAdmin.resolve` always tries to redirect somewhere on every admin request.
This should probably be triggered only during some specific cases.
ping @digi604 

mmh yeah. The idea was that if you changed the url of an object you are currently looking at you don't get a 404 when you hit refresh. we could limit it though so it would only take the current object model as a reference.


Resolving patch:
diff --git a/cms/admin/pageadmin.py b/cms/admin/pageadmin.py
--- a/cms/admin/pageadmin.py
+++ b/cms/admin/pageadmin.py
@@ -1,6 +1,7 @@
 # -*- coding: utf-8 -*-
 from functools import wraps
 import sys
+from cms.toolbar_pool import toolbar_pool
 from cms.constants import PAGE_TYPES_ID
 
 import django
@@ -1244,14 +1245,15 @@ def resolve(self, request):
             log = LogEntry.objects.get(pk=request.session['cms_log_latest'])
             obj = log.get_edited_object()
             del request.session['cms_log_latest']
-            try:
-                return HttpResponse(force_unicode(obj.get_absolute_url()))
-            except:
-                pass
+            if obj.__class__ in toolbar_pool.get_watch_models() and hasattr(obj, 'get_absolute_url'):
+                try:
+                    return HttpResponse(force_unicode(obj.get_absolute_url()))
+                except:
+                    pass
         pk = request.REQUEST.get('pk')
-
-        try:
-            app_label, model = request.REQUEST.get('model').split('.')
+        full_model = request.REQUEST.get('model')
+        if pk and full_model:
+            app_label, model = full_model.split('.')
             if pk and app_label:
                 ctype = ContentType.objects.get(app_label=app_label, model=model)
                 try:
@@ -1259,10 +1261,7 @@ def resolve(self, request):
                 except ctype.model_class().DoesNotExist:
                     return HttpResponse('/')
                 return HttpResponse(force_unicode(instance.get_absolute_url()))
-        except ValueError:
-            pass
-
-        return HttpResponse('/')
+        return HttpResponse('')
 
     def lookup_allowed(self, key, *args, **kwargs):
         if key == 'site__exact':
diff --git a/cms/cms_toolbar.py b/cms/cms_toolbar.py
--- a/cms/cms_toolbar.py
+++ b/cms/cms_toolbar.py
@@ -11,7 +11,7 @@
 from cms.compat import user_model_label
 from cms.constants import TEMPLATE_INHERITANCE_MAGIC
 from cms.exceptions import LanguageError
-from cms.models import Title
+from cms.models import Title, Page
 from cms.toolbar.items import TemplateItem
 from cms.toolbar_base import CMSToolbar
 from cms.toolbar_pool import toolbar_pool
@@ -150,7 +150,7 @@ def add_language_menu(self):
 
 @toolbar_pool.register
 class PageToolbar(CMSToolbar):
-    model = Title
+    watch_models = [Page]
 
     def populate(self):
         # always use draft if we have a page
diff --git a/cms/toolbar_pool.py b/cms/toolbar_pool.py
--- a/cms/toolbar_pool.py
+++ b/cms/toolbar_pool.py
@@ -55,4 +55,12 @@ def get_toolbars(self):
         self.discover_toolbars()
         return self.toolbars
 
+    def get_watch_models(self):
+        models = []
+        for toolbar in self.toolbars.values():
+            if hasattr(toolbar, 'watch_models'):
+                models += toolbar.watch_models
+        return models
+
+
 toolbar_pool = ToolbarPool()


Test patch:
diff --git a/cms/tests/toolbar.py b/cms/tests/toolbar.py
--- a/cms/tests/toolbar.py
+++ b/cms/tests/toolbar.py
@@ -297,7 +297,7 @@ def test_page_create_redirect(self):
         resolve_url = reverse('admin:cms_page_resolve')
         with self.login_user_context(superuser):
             response = self.client.post(resolve_url, {'pk': '', 'model': 'cms.page'})
-            self.assertEqual(response.content.decode('utf-8'), '/')
+            self.assertEqual(response.content.decode('utf-8'), '')
             page_data = self.get_new_page_data()
             self.client.post(URL_CMS_PAGE_ADD, page_data)