Repository: django-cms/django-cms

Issue:
render_model hvad model on apphook with 2 languages but one not published raises 500
following situation:

apphook with a hvad model.
one apphook page language is published. the other not. if both are published everything works. if one is not published (en) it raises 500. It could be that usersettings language is english. that would explain the english fallback.

cms/templatetags/cms_tags.py ? in render_tag

```
    data = self.get_context(context, **kwargs)
```

cms/templatetags/cms_tags.py ? in get_context

```
                                           view_url, view_method)
```

cms/templatetags/cms_tags.py ? in _get_data_context

```
    extra_context['attribute_name'] = attribute
     extra_context = self._get_empty_context(extra_context, instance,
                                             edit_fields, language, view_url,
                                             view_method)
     extra_context.update(self._get_content(extra_context, instance, attribute,
                                      language, filters))
     # content is for non-edit template content.html
     # rendered_content is for edit template plugin.html
     # in this templatetag both hold the same content
     extra_context['content'] = mark_safe(extra_context['content'])
     extra_context['rendered_content'] = extra_context['content']
```

'attribute' 
u'title'
'context'  
[{'False': False, 'None': None, 'True': True}, {'object': <Question: Versand: Bestehen Limiten beim Versand von E-Mails?>, 'question': <Question: Versand: Bestehen Limiten beim Versand von E-Mails?>, u'view': <aldryn_faq.views.FaqAnswerView object at 0x47c2410>}, {u'csrf_token': <django.utils.functional.__proxy__ object at 0x53a1990>}, {'perms': <django.contrib.auth.context_processors.PermWrapper object at 0x5394bd0>, 'user': <django.utils.functional.SimpleLazyObject object at 0x58326d0>}, {u'LANGUAGES':...
'edit_fields'  
None
'extra_context' 
[{'False': False, 'None': None, 'True': True}, {'object': <Question: Versand: Bestehen Limiten beim Versand von E-Mails?>, 'question': <Question: Versand: Bestehen Limiten beim Versand von E-Mails?>, u'view': <aldryn_faq.views.FaqAnswerView object at 0x47c2410>}, {u'csrf_token': <django.utils.functional.__proxy__ object at 0x53a1990>}, {'perms': <django.contrib.auth.context_processors.PermWrapper object at 0x5394bd0>, 'user': <django.utils.functional.SimpleLazyObject object at 0x58326d0>}, {u'LANGUAGES':...
'filters'  
None
'instance'  
<Question: Versand: Bestehen Limiten beim Versand von E-Mails?>
'language'  
None
'self'  
<Tag: render_model>
'view_method'  
None
'view_url'  
None
Kontext einklappen
cms/templatetags/cms_tags.py ? in _get_content

```
    extra_context['content'] = getattr(instance, attribute, '')
```

hvad/descriptors.py ? in **get**

```
def __get__(self, instance, instance_type=None):
     if not instance:
         # Don't raise an attribute error so we can use it in admin.
         return self.opts.translations_model._meta.get_field_by_name(
                                                 self.name)[0].default
     return getattr(self.translation(instance), self.name)

 def __set__(self, instance, value):
     setattr(self.translation(instance), self.name, value)

 def __delete__(self, instance):
```

'instance'  
<Question: Versand: Bestehen Limiten beim Versand von E-Mails?>
'instance_type' 
<class 'aldryn_faq.models.Question'>
'self'  
<hvad.descriptors.TranslatedAttribute object at 0x3560c50>
hvad/descriptors.py ? in translation

```
    self.opts = opts

 def translation(self, instance):
     cached = getattr(instance, self.opts.translations_cache, None)
     if not cached:
         cached = get_translation(instance)
         setattr(instance, self.opts.translations_cache, cached)
     return cached
```

 class TranslatedAttribute(BaseDescriptor):
'cached'  
None
'instance'  
<Question: Versand: Bestehen Limiten beim Versand von E-Mails?>
'self'  
<hvad.descriptors.TranslatedAttribute object at 0x3560c50>
hvad/utils.py ? in get_translation

def get_translation(instance, language_code=None):
     opts = instance._meta
     if not language_code:
         language_code = get_language()
     accessor = getattr(instance, opts.translations_accessor)
     return accessor.get(language_code=language_code)
 def get_translation_aware_manager(model):
     from nani.manager import TranslationAwareManager
     manager = TranslationAwareManager()
     manager.model = model
'accessor'  
<django.db.models.fields.related.RelatedManager object at 0x4d95c50>
'instance'  
<Question: Versand: Bestehen Limiten beim Versand von E-Mails?>
'language_code' 
u'en'
'opts'  
<Options for Question>
django/db/models/manager.py ? in get

```
    return self.get_query_set().get(*args, **kwargs)
```

django/db/models/query.py ? in get

```
    if num == 1:
         return clone._result_cache[0]
     if not num:
         raise self.model.DoesNotExist(
             "%s matching query does not exist." %
             self.model._meta.object_name)
     raise self.model.MultipleObjectsReturned(
         "get() returned more than one %s -- it returned %s!" %
         (self.model._meta.object_name, num))
 def create(self, **kwargs):
```

'args'  
Index   Wert
'clone' 
<QuerySet: model=QuestionTranslation>
'kwargs'  
'language_code' 
u'en'
'num'  
0
'self'  
<QuerySet: model=QuestionTranslation>



Discussion:
Is this duplicate of #2602?


Resolving patch:
diff --git a/cms/templatetags/cms_tags.py b/cms/templatetags/cms_tags.py
--- a/cms/templatetags/cms_tags.py
+++ b/cms/templatetags/cms_tags.py
@@ -742,7 +742,10 @@ def _get_content(self, context, instance, attribute, language, filters):
         Renders the requested attribute
         """
         extra_context = copy(context)
-        extra_context['content'] = getattr(instance, attribute, '')
+        if hasattr(instance, 'lazy_translation_getter'):
+            extra_context['content'] = instance.lazy_translation_getter(attribute, '')
+        else:
+            extra_context['content'] = getattr(instance, attribute, '')
         # This allow the requested item to be a method, a property or an
         # attribute
         if callable(extra_context['content']):


Test patch:
diff --git a/cms/test_utils/project/placeholderapp/views.py b/cms/test_utils/project/placeholderapp/views.py
--- a/cms/test_utils/project/placeholderapp/views.py
+++ b/cms/test_utils/project/placeholderapp/views.py
@@ -41,6 +41,13 @@ def detail_view_multi(request, pk, template_name='detail_multi.html',
                         template_string)
 
 
+def detail_view_multi_unfiltered(request, pk, template_name='detail_multi.html',
+                                 item_name="char_1", template_string='',):
+    instance = MultilingualExample1.objects.get(pk=pk)
+    return _base_detail(request, instance, template_name, item_name,
+                        template_string)
+
+
 def list_view(request):
     context = RequestContext(request)
     context['examples'] = Example1.objects.all()
diff --git a/cms/tests/plugins.py b/cms/tests/plugins.py
--- a/cms/tests/plugins.py
+++ b/cms/tests/plugins.py
@@ -606,8 +606,7 @@ def test_inheritplugin_media(self):
         self.client.logout()
         response = self.client.get(page.get_absolute_url())
         self.assertTrue(
-            'https://maps-api-ssl.google.com/maps/api/js?v=3&sensor=true' in response.content.decode('utf8'),
-            response.content)
+            'https://maps-api-ssl.google.com/maps/api/js?v=3&amp;sensor=true' in response.content.decode('utf8'))
 
     def test_inherit_plugin_with_empty_plugin(self):
         inheritfrompage = api.create_page('page to inherit from',
diff --git a/cms/tests/toolbar.py b/cms/tests/toolbar.py
--- a/cms/tests/toolbar.py
+++ b/cms/tests/toolbar.py
@@ -16,14 +16,18 @@
 from cms.api import create_page, create_title
 from cms.cms_toolbar import ADMIN_MENU_IDENTIFIER, ADMINISTRATION_BREAK
 from cms.compat import is_user_swapped
-from cms.toolbar.items import ToolbarAPIMixin, LinkItem, ItemSearchResult, Break, SubMenu, \
-    AjaxItem
+from cms.toolbar.items import (ToolbarAPIMixin, LinkItem, ItemSearchResult,
+                               Break, SubMenu, AjaxItem)
 from cms.toolbar.toolbar import CMSToolbar
 from cms.middleware.toolbar import ToolbarMiddleware
-from cms.test_utils.testcases import SettingsOverrideTestCase, URL_CMS_PAGE_ADD, URL_CMS_PAGE_CHANGE
+from cms.test_utils.testcases import (SettingsOverrideTestCase,
+                                      URL_CMS_PAGE_ADD, URL_CMS_PAGE_CHANGE)
 from cms.test_utils.util.context_managers import SettingsOverride
-from cms.test_utils.project.placeholderapp.models import (Example1, MultilingualExample1)
-from cms.test_utils.project.placeholderapp.views import detail_view, detail_view_multi
+from cms.test_utils.project.placeholderapp.models import (Example1,
+                                                          MultilingualExample1)
+from cms.test_utils.project.placeholderapp.views import (detail_view,
+                                                         detail_view_multi,
+                                                         detail_view_multi_unfiltered)
 
 
 class ToolbarTestBase(SettingsOverrideTestCase):
@@ -973,6 +977,37 @@ def test_multi_edit(self):
             self.assertContains(response, "/admin/placeholderapp/multilingualexample1/edit-field/%s/fr/" % exm.pk)
             self.assertTrue(re.search(self.edit_fields_rx % "char_1%2Cchar_2", response.content.decode('utf8')))
 
+    def test_multi_edit_no500(self):
+        user = self.get_staff()
+        page = create_page('Test', 'col_two.html', 'en', published=True)
+        title = create_title("fr", "test", page)
+
+        exm = MultilingualExample1()
+        exm.translate("fr")
+        exm.char_1 = "un"
+        exm.char_2 = "deux"
+        exm.save()
+
+        with SettingsOverride(LANGUAGE_CODE="fr"):
+            request = self.get_page_request(title.page, user, edit=True, lang_code="fr")
+            response = detail_view_multi_unfiltered(request, exm.pk)
+            self.assertContains(
+                response,
+                '<h1><div class="cms_plugin cms_plugin-%s-%s-%s-%s cms_render_model">un</div></h1>' % (
+                    'placeholderapp', 'multilingualexample1', 'char_1', exm.pk))
+            self.assertContains(response, "/admin/placeholderapp/multilingualexample1/edit-field/%s/fr/" % exm.pk)
+            self.assertTrue(re.search(self.edit_fields_rx % "char_1%2Cchar_2", response.content.decode('utf8')))
+
+        with SettingsOverride(LANGUAGE_CODE="de"):
+            request = self.get_page_request(title.page, user, edit=True, lang_code="de")
+            response = detail_view_multi_unfiltered(request, exm.pk)
+            self.assertContains(
+                response,
+                '<h1><div class="cms_plugin cms_plugin-%s-%s-%s-%s cms_render_model">un</div></h1>' % (
+                    'placeholderapp', 'multilingualexample1', 'char_1', exm.pk))
+            self.assertContains(response, "/admin/placeholderapp/multilingualexample1/edit-field/%s/de/" % exm.pk)
+            self.assertTrue(re.search(self.edit_fields_rx % "char_1%2Cchar_2", response.content.decode('utf8')))
+
     def test_edit_field_multilingual(self):
         from django.contrib.admin import site