We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Don't use objects.get in best_language_title()
Reproduce bug:
There must be at least one page without english translation. Then edit a page in the english backend. => Error

Reason:
To show the page in the page mirroring drop down menu, the root language of the region is used. A language node of the region is chosen by `LanguageTreeNode.objects.get(region__id=self.region.id)`.
But get() apparently only works if there is excactly one matching object. So it would only work if the region had only one language at all.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `backend/cms/models/page.py`
Content:
```
1 """Models representing a page and page translation with content
2 """
3 
4 import logging
5 
6 from django.db import models
7 from django.conf import settings
8 from django.urls import reverse
9 from django.utils import timezone
10 from django.utils.translation import get_language
11 
12 from mptt.models import MPTTModel, TreeForeignKey
13 
14 from .language import Language, LanguageTreeNode
15 from .region import Region
16 from ..constants import status
17 
18 
19 logger = logging.getLogger(__name__)
20 
21 
22 class Page(MPTTModel):
23     """Class that represents an Page database object
24 
25     Args:
26         MPTTModel : Library for hierachical data structures
27     """
28 
29     parent = TreeForeignKey(
30         'self',
31         blank=True,
32         null=True,
33         related_name='children',
34         on_delete=models.PROTECT
35     )
36     icon = models.ImageField(
37         blank=True,
38         null=True,
39         upload_to='pages/%Y/%m/%d'
40     )
41     region = models.ForeignKey(Region, related_name='pages', on_delete=models.CASCADE)
42     archived = models.BooleanField(default=False)
43     mirrored_page = models.ForeignKey('self', null=True, blank=True, on_delete=models.PROTECT)
44     mirrored_page_first = models.BooleanField(default=True)
45     editors = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='editors', blank=True)
46     publishers = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='publishers', blank=True)
47     created_date = models.DateTimeField(default=timezone.now)
48     last_updated = models.DateTimeField(auto_now=True)
49 
50     @property
51     def depth(self):
52         """Provide level of inheritance
53 
54         Returns:
55             Int : Number of ancestors
56         """
57 
58         return len(self.get_ancestors())
59 
60     @property
61     def languages(self):
62         page_translations = self.page_translations.prefetch_related('language').all()
63         languages = []
64         for page_translation in page_translations:
65             if page_translation.language not in languages:
66                 languages.append(page_translation.language)
67         return languages
68 
69     def get_translation(self, language_code):
70         return self.page_translations.filter(
71             language__code=language_code
72         ).first()
73 
74     # Helper function for page labels, second level paths etc. where the ancestor translation might not exist
75     def get_first_translation(self, priority_language_codes=None):
76         # Taking [] directly as default parameter would be dangerous because it is mutable
77         if not priority_language_codes:
78             priority_language_codes = []
79         for language_code in priority_language_codes + ['en-us', 'de-de']:
80             if self.page_translations.filter(language__code=language_code).exists():
81                 return self.page_translations.filter(language__code=language_code).first()
82         return self.page_translations.first()
83 
84     def get_public_translation(self, language_code):
85         return self.page_translations.filter(
86             language__code=language_code,
87             status=status.PUBLIC,
88         ).first()
89 
90     def get_mirrored_text(self, language_code):
91         """
92         This content needs to be added when delivering content to end users
93         """
94         return self.mirrored_page.get_translation(language_code).text
95 
96     def get_absolute_url(self):
97         return reverse('edit_page', kwargs={
98             'page_id': self.id,
99             'region_slug': self.region.slug,
100             'language_code': self.region.default_language.code,
101         })
102 
103     @staticmethod
104     def get_archived(region_slug):
105         return Page.objects.filter(archived=True, region__slug=region_slug)
106 
107     @staticmethod
108     def archived_count(region_slug):
109         return Page.objects.filter(archived=True, region__slug=region_slug).count()
110 
111     def __str__(self):
112         first_translation = self.get_first_translation()
113         return '(id: {}, slug: {} ({}))'.format(self.id, first_translation.slug, first_translation.language.code)
114 
115     @classmethod
116     def get_tree(cls, region_slug, archived=False):
117         """Function for building up a Treeview of all pages
118 
119         Args:
120             region_slug: slug of the region the page belongs to
121             archived:  if true archived pages will be included
122 
123         Returns:
124             [pages]: Array of pages connected with their relations
125         """
126 
127         if archived:
128             pages = cls.objects.all().prefetch_related(
129                 'page_translations'
130             ).filter(
131                 region__slug=region_slug
132             )
133         else:
134             pages = cls.objects.all().prefetch_related(
135                 'page_translations'
136             ).filter(
137                 region__slug=region_slug,
138                 archived=False
139             )
140 
141         return pages
142 
143     def best_language_title(self):
144         page_translation = self.page_translations.filter(language__code=get_language())
145         if not page_translation:
146             alt_code = LanguageTreeNode.objects.get(region__id=self.region.id).get_root().language.code
147             page_translation = self.page_translations.filter(language__code=alt_code)
148         return page_translation.first().title
149 
150     class Meta:
151         default_permissions = ()
152         permissions = (
153             ('view_pages', 'Can view pages'),
154             ('edit_pages', 'Can edit pages'),
155             ('publish_pages', 'Can publish pages'),
156             ('grant_page_permissions', 'Can grant page permissions'),
157         )
158 
159 
160 class PageTranslation(models.Model):
161     """Class defining a Translation of a Page
162 
163     Args:
164         models : Class inherit of django-Models
165     """
166 
167     page = models.ForeignKey(Page, related_name='page_translations', on_delete=models.CASCADE)
168     language = models.ForeignKey(
169         Language,
170         related_name='page_translations',
171         on_delete=models.CASCADE
172     )
173     slug = models.SlugField(max_length=200, blank=True, allow_unicode=True)
174     title = models.CharField(max_length=250)
175     text = models.TextField()
176     status = models.CharField(max_length=6, choices=status.CHOICES, default=status.DRAFT)
177     currently_in_translation = models.BooleanField(default=False)
178     version = models.PositiveIntegerField(default=0)
179     minor_edit = models.BooleanField(default=False)
180     creator = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, on_delete=models.SET_NULL)
181     created_date = models.DateTimeField(default=timezone.now)
182     last_updated = models.DateTimeField(auto_now=True)
183 
184     @property
185     def ancestor_path(self):
186         return '/'.join([
187             ancestor.get_first_translation([self.language.code]).slug
188             for ancestor in self.page.get_ancestors()
189         ])
190 
191     @property
192     def permalink(self):
193         return '{}/{}/{}/{}'.format(
194             self.page.region.slug, self.language.code, self.ancestor_path, self.slug
195         )
196 
197     @property
198     def available_languages(self):
199         languages = self.page.languages
200         languages.remove(self.language)
201         available_languages = {}
202         for language in languages:
203             other_translation = self.page.get_public_translation(language.code)
204             if other_translation:
205                 available_languages[language.code] = {
206                     'id': other_translation.id,
207                     'url': other_translation.permalink
208                 }
209         return available_languages
210 
211     @property
212     def source_translation(self):
213         source_language_tree_node = self.page.region.language_tree_nodes.get(language=self.language).parent
214         if source_language_tree_node:
215             return self.page.get_translation(source_language_tree_node.code)
216         return None
217 
218     @property
219     def latest_public_revision(self):
220         return self.page.page_translations.filter(
221             language=self.language,
222             status=status.PUBLIC,
223         ).first()
224 
225     @property
226     def latest_major_revision(self):
227         return self.page.page_translations.filter(
228             language=self.language,
229             minor_edit=False,
230         ).first()
231 
232     @property
233     def latest_major_public_revision(self):
234         return self.page.page_translations.filter(
235             language=self.language,
236             status=status.PUBLIC,
237             minor_edit=False,
238         ).first()
239 
240     @property
241     def previous_revision(self):
242         version = self.version - 1
243         return self.page.page_translations.filter(
244             language=self.language,
245             version=version,
246         ).first()
247 
248     @property
249     def is_outdated(self):
250         source_translation = self.source_translation
251         # If self.language is the root language, this translation can never be outdated
252         if not source_translation:
253             return False
254         # If the source translation is outdated, this translation can not be up to date
255         if source_translation.is_outdated:
256             return True
257         self_revision = self.latest_major_public_revision
258         source_revision = source_translation.latest_major_public_revision
259         # If on of the translations has no major public revision, it cannot be outdated
260         if not self_revision or not source_revision:
261             return False
262         return self_revision.last_updated < source_revision.last_updated
263 
264     @property
265     def combined_text(self):
266         """
267         Combines the text from the PageTranslation with the text from the mirrored page.
268         """
269         if self.page.mirrored_page_first:
270             return self.page.get_mirrored_text(self.language.code) + self.text
271         return self.text + self.page.get_mirrored_text(self.language.code)
272 
273     def __str__(self):
274         return '(id: {}, lang: {}, slug: {})'.format(self.id, self.language.code, self.slug)
275 
276     class Meta:
277         ordering = ['page', '-version']
278         default_permissions = ()
279
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/backend/cms/models/page.py b/backend/cms/models/page.py
--- a/backend/cms/models/page.py
+++ b/backend/cms/models/page.py
@@ -11,7 +11,7 @@
 
 from mptt.models import MPTTModel, TreeForeignKey
 
-from .language import Language, LanguageTreeNode
+from .language import Language
 from .region import Region
 from ..constants import status
 
@@ -143,7 +143,7 @@
     def best_language_title(self):
         page_translation = self.page_translations.filter(language__code=get_language())
         if not page_translation:
-            alt_code = LanguageTreeNode.objects.get(region__id=self.region.id).get_root().language.code
+            alt_code = self.region.default_language.code
             page_translation = self.page_translations.filter(language__code=alt_code)
         return page_translation.first().title

{"golden_diff": "diff --git a/backend/cms/models/page.py b/backend/cms/models/page.py\n--- a/backend/cms/models/page.py\n+++ b/backend/cms/models/page.py\n@@ -11,7 +11,7 @@\n \n from mptt.models import MPTTModel, TreeForeignKey\n \n-from .language import Language, LanguageTreeNode\n+from .language import Language\n from .region import Region\n from ..constants import status\n \n@@ -143,7 +143,7 @@\n     def best_language_title(self):\n         page_translation = self.page_translations.filter(language__code=get_language())\n         if not page_translation:\n-            alt_code = LanguageTreeNode.objects.get(region__id=self.region.id).get_root().language.code\n+            alt_code = self.region.default_language.code\n             page_translation = self.page_translations.filter(language__code=alt_code)\n         return page_translation.first().title\n", "issue": "Don't use objects.get in best_language_title()\nReproduce bug:\r\nThere must be at least one page without english translation. Then edit a page in the english backend. => Error\r\n\r\nReason:\r\nTo show the page in the page mirroring drop down menu, the root language of the region is used. A language node of the region is chosen by `LanguageTreeNode.objects.get(region__id=self.region.id)`.\r\nBut get() apparently only works if there is excactly one matching object. So it would only work if the region had only one language at all.\n", "before_files": [{"content": "\"\"\"Models representing a page and page translation with content\n\"\"\"\n\nimport logging\n\nfrom django.db import models\nfrom django.conf import settings\nfrom django.urls import reverse\nfrom django.utils import timezone\nfrom django.utils.translation import get_language\n\nfrom mptt.models import MPTTModel, TreeForeignKey\n\nfrom .language import Language, LanguageTreeNode\nfrom .region import Region\nfrom ..constants import status\n\n\nlogger = logging.getLogger(__name__)\n\n\nclass Page(MPTTModel):\n    \"\"\"Class that represents an Page database object\n\n    Args:\n        MPTTModel : Library for hierachical data structures\n    \"\"\"\n\n    parent = TreeForeignKey(\n        'self',\n        blank=True,\n        null=True,\n        related_name='children',\n        on_delete=models.PROTECT\n    )\n    icon = models.ImageField(\n        blank=True,\n        null=True,\n        upload_to='pages/%Y/%m/%d'\n    )\n    region = models.ForeignKey(Region, related_name='pages', on_delete=models.CASCADE)\n    archived = models.BooleanField(default=False)\n    mirrored_page = models.ForeignKey('self', null=True, blank=True, on_delete=models.PROTECT)\n    mirrored_page_first = models.BooleanField(default=True)\n    editors = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='editors', blank=True)\n    publishers = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='publishers', blank=True)\n    created_date = models.DateTimeField(default=timezone.now)\n    last_updated = models.DateTimeField(auto_now=True)\n\n    @property\n    def depth(self):\n        \"\"\"Provide level of inheritance\n\n        Returns:\n            Int : Number of ancestors\n        \"\"\"\n\n        return len(self.get_ancestors())\n\n    @property\n    def languages(self):\n        page_translations = self.page_translations.prefetch_related('language').all()\n        languages = []\n        for page_translation in page_translations:\n            if page_translation.language not in languages:\n                languages.append(page_translation.language)\n        return languages\n\n    def get_translation(self, language_code):\n        return self.page_translations.filter(\n            language__code=language_code\n        ).first()\n\n    # Helper function for page labels, second level paths etc. where the ancestor translation might not exist\n    def get_first_translation(self, priority_language_codes=None):\n        # Taking [] directly as default parameter would be dangerous because it is mutable\n        if not priority_language_codes:\n            priority_language_codes = []\n        for language_code in priority_language_codes + ['en-us', 'de-de']:\n            if self.page_translations.filter(language__code=language_code).exists():\n                return self.page_translations.filter(language__code=language_code).first()\n        return self.page_translations.first()\n\n    def get_public_translation(self, language_code):\n        return self.page_translations.filter(\n            language__code=language_code,\n            status=status.PUBLIC,\n        ).first()\n\n    def get_mirrored_text(self, language_code):\n        \"\"\"\n        This content needs to be added when delivering content to end users\n        \"\"\"\n        return self.mirrored_page.get_translation(language_code).text\n\n    def get_absolute_url(self):\n        return reverse('edit_page', kwargs={\n            'page_id': self.id,\n            'region_slug': self.region.slug,\n            'language_code': self.region.default_language.code,\n        })\n\n    @staticmethod\n    def get_archived(region_slug):\n        return Page.objects.filter(archived=True, region__slug=region_slug)\n\n    @staticmethod\n    def archived_count(region_slug):\n        return Page.objects.filter(archived=True, region__slug=region_slug).count()\n\n    def __str__(self):\n        first_translation = self.get_first_translation()\n        return '(id: {}, slug: {} ({}))'.format(self.id, first_translation.slug, first_translation.language.code)\n\n    @classmethod\n    def get_tree(cls, region_slug, archived=False):\n        \"\"\"Function for building up a Treeview of all pages\n\n        Args:\n            region_slug: slug of the region the page belongs to\n            archived:  if true archived pages will be included\n\n        Returns:\n            [pages]: Array of pages connected with their relations\n        \"\"\"\n\n        if archived:\n            pages = cls.objects.all().prefetch_related(\n                'page_translations'\n            ).filter(\n                region__slug=region_slug\n            )\n        else:\n            pages = cls.objects.all().prefetch_related(\n                'page_translations'\n            ).filter(\n                region__slug=region_slug,\n                archived=False\n            )\n\n        return pages\n\n    def best_language_title(self):\n        page_translation = self.page_translations.filter(language__code=get_language())\n        if not page_translation:\n            alt_code = LanguageTreeNode.objects.get(region__id=self.region.id).get_root().language.code\n            page_translation = self.page_translations.filter(language__code=alt_code)\n        return page_translation.first().title\n\n    class Meta:\n        default_permissions = ()\n        permissions = (\n            ('view_pages', 'Can view pages'),\n            ('edit_pages', 'Can edit pages'),\n            ('publish_pages', 'Can publish pages'),\n            ('grant_page_permissions', 'Can grant page permissions'),\n        )\n\n\nclass PageTranslation(models.Model):\n    \"\"\"Class defining a Translation of a Page\n\n    Args:\n        models : Class inherit of django-Models\n    \"\"\"\n\n    page = models.ForeignKey(Page, related_name='page_translations', on_delete=models.CASCADE)\n    language = models.ForeignKey(\n        Language,\n        related_name='page_translations',\n        on_delete=models.CASCADE\n    )\n    slug = models.SlugField(max_length=200, blank=True, allow_unicode=True)\n    title = models.CharField(max_length=250)\n    text = models.TextField()\n    status = models.CharField(max_length=6, choices=status.CHOICES, default=status.DRAFT)\n    currently_in_translation = models.BooleanField(default=False)\n    version = models.PositiveIntegerField(default=0)\n    minor_edit = models.BooleanField(default=False)\n    creator = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, on_delete=models.SET_NULL)\n    created_date = models.DateTimeField(default=timezone.now)\n    last_updated = models.DateTimeField(auto_now=True)\n\n    @property\n    def ancestor_path(self):\n        return '/'.join([\n            ancestor.get_first_translation([self.language.code]).slug\n            for ancestor in self.page.get_ancestors()\n        ])\n\n    @property\n    def permalink(self):\n        return '{}/{}/{}/{}'.format(\n            self.page.region.slug, self.language.code, self.ancestor_path, self.slug\n        )\n\n    @property\n    def available_languages(self):\n        languages = self.page.languages\n        languages.remove(self.language)\n        available_languages = {}\n        for language in languages:\n            other_translation = self.page.get_public_translation(language.code)\n            if other_translation:\n                available_languages[language.code] = {\n                    'id': other_translation.id,\n                    'url': other_translation.permalink\n                }\n        return available_languages\n\n    @property\n    def source_translation(self):\n        source_language_tree_node = self.page.region.language_tree_nodes.get(language=self.language).parent\n        if source_language_tree_node:\n            return self.page.get_translation(source_language_tree_node.code)\n        return None\n\n    @property\n    def latest_public_revision(self):\n        return self.page.page_translations.filter(\n            language=self.language,\n            status=status.PUBLIC,\n        ).first()\n\n    @property\n    def latest_major_revision(self):\n        return self.page.page_translations.filter(\n            language=self.language,\n            minor_edit=False,\n        ).first()\n\n    @property\n    def latest_major_public_revision(self):\n        return self.page.page_translations.filter(\n            language=self.language,\n            status=status.PUBLIC,\n            minor_edit=False,\n        ).first()\n\n    @property\n    def previous_revision(self):\n        version = self.version - 1\n        return self.page.page_translations.filter(\n            language=self.language,\n            version=version,\n        ).first()\n\n    @property\n    def is_outdated(self):\n        source_translation = self.source_translation\n        # If self.language is the root language, this translation can never be outdated\n        if not source_translation:\n            return False\n        # If the source translation is outdated, this translation can not be up to date\n        if source_translation.is_outdated:\n            return True\n        self_revision = self.latest_major_public_revision\n        source_revision = source_translation.latest_major_public_revision\n        # If on of the translations has no major public revision, it cannot be outdated\n        if not self_revision or not source_revision:\n            return False\n        return self_revision.last_updated < source_revision.last_updated\n\n    @property\n    def combined_text(self):\n        \"\"\"\n        Combines the text from the PageTranslation with the text from the mirrored page.\n        \"\"\"\n        if self.page.mirrored_page_first:\n            return self.page.get_mirrored_text(self.language.code) + self.text\n        return self.text + self.page.get_mirrored_text(self.language.code)\n\n    def __str__(self):\n        return '(id: {}, lang: {}, slug: {})'.format(self.id, self.language.code, self.slug)\n\n    class Meta:\n        ordering = ['page', '-version']\n        default_permissions = ()\n", "path": "backend/cms/models/page.py"}], "after_files": [{"content": "\"\"\"Models representing a page and page translation with content\n\"\"\"\n\nimport logging\n\nfrom django.db import models\nfrom django.conf import settings\nfrom django.urls import reverse\nfrom django.utils import timezone\nfrom django.utils.translation import get_language\n\nfrom mptt.models import MPTTModel, TreeForeignKey\n\nfrom .language import Language\nfrom .region import Region\nfrom ..constants import status\n\n\nlogger = logging.getLogger(__name__)\n\n\nclass Page(MPTTModel):\n    \"\"\"Class that represents an Page database object\n\n    Args:\n        MPTTModel : Library for hierachical data structures\n    \"\"\"\n\n    parent = TreeForeignKey(\n        'self',\n        blank=True,\n        null=True,\n        related_name='children',\n        on_delete=models.PROTECT\n    )\n    icon = models.ImageField(\n        blank=True,\n        null=True,\n        upload_to='pages/%Y/%m/%d'\n    )\n    region = models.ForeignKey(Region, related_name='pages', on_delete=models.CASCADE)\n    archived = models.BooleanField(default=False)\n    mirrored_page = models.ForeignKey('self', null=True, blank=True, on_delete=models.PROTECT)\n    mirrored_page_first = models.BooleanField(default=True)\n    editors = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='editors', blank=True)\n    publishers = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='publishers', blank=True)\n    created_date = models.DateTimeField(default=timezone.now)\n    last_updated = models.DateTimeField(auto_now=True)\n\n    @property\n    def depth(self):\n        \"\"\"Provide level of inheritance\n\n        Returns:\n            Int : Number of ancestors\n        \"\"\"\n\n        return len(self.get_ancestors())\n\n    @property\n    def languages(self):\n        page_translations = self.page_translations.prefetch_related('language').all()\n        languages = []\n        for page_translation in page_translations:\n            if page_translation.language not in languages:\n                languages.append(page_translation.language)\n        return languages\n\n    def get_translation(self, language_code):\n        return self.page_translations.filter(\n            language__code=language_code\n        ).first()\n\n    # Helper function for page labels, second level paths etc. where the ancestor translation might not exist\n    def get_first_translation(self, priority_language_codes=None):\n        # Taking [] directly as default parameter would be dangerous because it is mutable\n        if not priority_language_codes:\n            priority_language_codes = []\n        for language_code in priority_language_codes + ['en-us', 'de-de']:\n            if self.page_translations.filter(language__code=language_code).exists():\n                return self.page_translations.filter(language__code=language_code).first()\n        return self.page_translations.first()\n\n    def get_public_translation(self, language_code):\n        return self.page_translations.filter(\n            language__code=language_code,\n            status=status.PUBLIC,\n        ).first()\n\n    def get_mirrored_text(self, language_code):\n        \"\"\"\n        This content needs to be added when delivering content to end users\n        \"\"\"\n        return self.mirrored_page.get_translation(language_code).text\n\n    def get_absolute_url(self):\n        return reverse('edit_page', kwargs={\n            'page_id': self.id,\n            'region_slug': self.region.slug,\n            'language_code': self.region.default_language.code,\n        })\n\n    @staticmethod\n    def get_archived(region_slug):\n        return Page.objects.filter(archived=True, region__slug=region_slug)\n\n    @staticmethod\n    def archived_count(region_slug):\n        return Page.objects.filter(archived=True, region__slug=region_slug).count()\n\n    def __str__(self):\n        first_translation = self.get_first_translation()\n        return '(id: {}, slug: {} ({}))'.format(self.id, first_translation.slug, first_translation.language.code)\n\n    @classmethod\n    def get_tree(cls, region_slug, archived=False):\n        \"\"\"Function for building up a Treeview of all pages\n\n        Args:\n            region_slug: slug of the region the page belongs to\n            archived:  if true archived pages will be included\n\n        Returns:\n            [pages]: Array of pages connected with their relations\n        \"\"\"\n\n        if archived:\n            pages = cls.objects.all().prefetch_related(\n                'page_translations'\n            ).filter(\n                region__slug=region_slug\n            )\n        else:\n            pages = cls.objects.all().prefetch_related(\n                'page_translations'\n            ).filter(\n                region__slug=region_slug,\n                archived=False\n            )\n\n        return pages\n\n    def best_language_title(self):\n        page_translation = self.page_translations.filter(language__code=get_language())\n        if not page_translation:\n            alt_code = self.region.default_language.code\n            page_translation = self.page_translations.filter(language__code=alt_code)\n        return page_translation.first().title\n\n    class Meta:\n        default_permissions = ()\n        permissions = (\n            ('view_pages', 'Can view pages'),\n            ('edit_pages', 'Can edit pages'),\n            ('publish_pages', 'Can publish pages'),\n            ('grant_page_permissions', 'Can grant page permissions'),\n        )\n\n\nclass PageTranslation(models.Model):\n    \"\"\"Class defining a Translation of a Page\n\n    Args:\n        models : Class inherit of django-Models\n    \"\"\"\n\n    page = models.ForeignKey(Page, related_name='page_translations', on_delete=models.CASCADE)\n    language = models.ForeignKey(\n        Language,\n        related_name='page_translations',\n        on_delete=models.CASCADE\n    )\n    slug = models.SlugField(max_length=200, blank=True, allow_unicode=True)\n    title = models.CharField(max_length=250)\n    text = models.TextField()\n    status = models.CharField(max_length=6, choices=status.CHOICES, default=status.DRAFT)\n    currently_in_translation = models.BooleanField(default=False)\n    version = models.PositiveIntegerField(default=0)\n    minor_edit = models.BooleanField(default=False)\n    creator = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, on_delete=models.SET_NULL)\n    created_date = models.DateTimeField(default=timezone.now)\n    last_updated = models.DateTimeField(auto_now=True)\n\n    @property\n    def ancestor_path(self):\n        return '/'.join([\n            ancestor.get_first_translation([self.language.code]).slug\n            for ancestor in self.page.get_ancestors()\n        ])\n\n    @property\n    def permalink(self):\n        return '{}/{}/{}/{}'.format(\n            self.page.region.slug, self.language.code, self.ancestor_path, self.slug\n        )\n\n    @property\n    def available_languages(self):\n        languages = self.page.languages\n        languages.remove(self.language)\n        available_languages = {}\n        for language in languages:\n            other_translation = self.page.get_public_translation(language.code)\n            if other_translation:\n                available_languages[language.code] = {\n                    'id': other_translation.id,\n                    'url': other_translation.permalink\n                }\n        return available_languages\n\n    @property\n    def source_translation(self):\n        source_language_tree_node = self.page.region.language_tree_nodes.get(language=self.language).parent\n        if source_language_tree_node:\n            return self.page.get_translation(source_language_tree_node.code)\n        return None\n\n    @property\n    def latest_public_revision(self):\n        return self.page.page_translations.filter(\n            language=self.language,\n            status=status.PUBLIC,\n        ).first()\n\n    @property\n    def latest_major_revision(self):\n        return self.page.page_translations.filter(\n            language=self.language,\n            minor_edit=False,\n        ).first()\n\n    @property\n    def latest_major_public_revision(self):\n        return self.page.page_translations.filter(\n            language=self.language,\n            status=status.PUBLIC,\n            minor_edit=False,\n        ).first()\n\n    @property\n    def previous_revision(self):\n        version = self.version - 1\n        return self.page.page_translations.filter(\n            language=self.language,\n            version=version,\n        ).first()\n\n    @property\n    def is_outdated(self):\n        source_translation = self.source_translation\n        # If self.language is the root language, this translation can never be outdated\n        if not source_translation:\n            return False\n        # If the source translation is outdated, this translation can not be up to date\n        if source_translation.is_outdated:\n            return True\n        self_revision = self.latest_major_public_revision\n        source_revision = source_translation.latest_major_public_revision\n        # If on of the translations has no major public revision, it cannot be outdated\n        if not self_revision or not source_revision:\n            return False\n        return self_revision.last_updated < source_revision.last_updated\n\n    @property\n    def combined_text(self):\n        \"\"\"\n        Combines the text from the PageTranslation with the text from the mirrored page.\n        \"\"\"\n        if self.page.mirrored_page_first:\n            return self.page.get_mirrored_text(self.language.code) + self.text\n        return self.text + self.page.get_mirrored_text(self.language.code)\n\n    def __str__(self):\n        return '(id: {}, lang: {}, slug: {})'.format(self.id, self.language.code, self.slug)\n\n    class Meta:\n        ordering = ['page', '-version']\n        default_permissions = ()\n", "path": "backend/cms/models/page.py"}]}