We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Language tree node form not working
### Describe the Bug
<!-- A clear and concise description of what the bug is. -->
Since commit 928dec60b79ba47366099ca4227b2abe0acb2de7, the language node form is not working anymore.

### Steps to Reproduce

1. Go to a region
2. Open language tree
3. Open language tree node
4. Click on save

### Expected Behavior
<!-- A clear and concise description of what you expected to happen. -->
The language tree node should be saved

### Actual Behavior
<!-- A clear and concise description of what actually happened. -->
the following error appears:
```
MultipleObjectsReturned at /augsburg/language-tree/4/edit

get() returned more than one LanguageTreeNode -- it returned 3!
```
### Additional Information
<!-- Add any other context (e.g. logs, screenshots, etc.) about the problem here. -->
<details>
  <summary>Debug Stacktrace</summary>


Environment:


Request Method: POST
Request URL: http://localhost:8000/augsburg/language-tree/4/edit

Django Version: 2.2.16
Python Version: 3.7.9
Installed Applications:
['cms.apps.CmsConfig',
 'gvz_api.apps.GvzApiConfig',
 'django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.messages',
 'django.contrib.sessions',
 'django.contrib.sitemaps',
 'django.contrib.staticfiles',
 'compressor',
 'compressor_toolkit',
 'corsheaders',
 'widget_tweaks',
 'easy_thumbnails',
 'filer',
 'mptt',
 'rules.apps.AutodiscoverRulesConfig']
Installed Middleware:
['corsheaders.middleware.CorsMiddleware',
 'django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.locale.LocaleMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']



Traceback:

File "/home/timo/job/integreat/django/.venv/lib/python3.7/site-packages/django/core/handlers/exception.py" in inner
  34.             response = get_response(request)

File "/home/timo/job/integreat/django/.venv/lib/python3.7/site-packages/django/core/handlers/base.py" in _get_response
  115.                 response = self.process_exception_by_middleware(e, request)

File "/home/timo/job/integreat/django/.venv/lib/python3.7/site-packages/django/core/handlers/base.py" in _get_response
  113.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "/home/timo/job/integreat/django/.venv/lib/python3.7/site-packages/django/views/generic/base.py" in view
  71.             return self.dispatch(request, *args, **kwargs)

File "/home/timo/job/integreat/django/.venv/lib/python3.7/site-packages/django/utils/decorators.py" in _wrapper
  45.         return bound_method(*args, **kwargs)

File "/home/timo/job/integreat/django/.venv/lib/python3.7/site-packages/django/contrib/auth/decorators.py" in _wrapped_view
  21.                 return view_func(request, *args, **kwargs)

File "/home/timo/job/integreat/django/.venv/lib/python3.7/site-packages/django/utils/decorators.py" in _wrapper
  45.         return bound_method(*args, **kwargs)

File "/home/timo/job/integreat/django/src/cms/decorators.py" in wrap
  53.             return function(request, *args, **kwargs)

File "/home/timo/job/integreat/django/.venv/lib/python3.7/site-packages/django/contrib/auth/mixins.py" in dispatch
  85.         return super().dispatch(request, *args, **kwargs)

File "/home/timo/job/integreat/django/.venv/lib/python3.7/site-packages/django/views/generic/base.py" in dispatch
  97.         return handler(request, *args, **kwargs)

File "/home/timo/job/integreat/django/src/cms/views/language_tree/language_tree_node_view.py" in post
  58.         if not language_tree_node_form.is_valid():

File "/home/timo/job/integreat/django/.venv/lib/python3.7/site-packages/django/forms/forms.py" in is_valid
  185.         return self.is_bound and not self.errors

File "/home/timo/job/integreat/django/.venv/lib/python3.7/site-packages/django/forms/forms.py" in errors
  180.             self.full_clean()

File "/home/timo/job/integreat/django/.venv/lib/python3.7/site-packages/django/forms/forms.py" in full_clean
  381.         self._clean_fields()

File "/home/timo/job/integreat/django/.venv/lib/python3.7/site-packages/django/forms/forms.py" in _clean_fields
  399.                     value = field.clean(value)

File "/home/timo/job/integreat/django/.venv/lib/python3.7/site-packages/django/forms/fields.py" in clean
  148.         value = self.to_python(value)

File "/home/timo/job/integreat/django/.venv/lib/python3.7/site-packages/django/forms/models.py" in to_python
  1248.             value = self.queryset.get(**{key: value})

File "/home/timo/job/integreat/django/.venv/lib/python3.7/site-packages/django/db/models/query.py" in get
  412.             (self.model._meta.object_name, num)

Exception Type: MultipleObjectsReturned at /augsburg/language-tree/4/edit
Exception Value: get() returned more than one LanguageTreeNode -- it returned 3!
</details>

I assume that this is a bug in the mptt library - TreeQuerySets don't seem to work properly with the `difference()`-method...
Language tree node form not working
### Describe the Bug
<!-- A clear and concise description of what the bug is. -->
Since commit 928dec60b79ba47366099ca4227b2abe0acb2de7, the language node form is not working anymore.

### Steps to Reproduce

1. Go to a region
2. Open language tree
3. Open language tree node
4. Click on save

### Expected Behavior
<!-- A clear and concise description of what you expected to happen. -->
The language tree node should be saved

### Actual Behavior
<!-- A clear and concise description of what actually happened. -->
the following error appears:
```
MultipleObjectsReturned at /augsburg/language-tree/4/edit

get() returned more than one LanguageTreeNode -- it returned 3!
```
### Additional Information
<!-- Add any other context (e.g. logs, screenshots, etc.) about the problem here. -->
<details>
  <summary>Debug Stacktrace</summary>


Environment:


Request Method: POST
Request URL: http://localhost:8000/augsburg/language-tree/4/edit

Django Version: 2.2.16
Python Version: 3.7.9
Installed Applications:
['cms.apps.CmsConfig',
 'gvz_api.apps.GvzApiConfig',
 'django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.messages',
 'django.contrib.sessions',
 'django.contrib.sitemaps',
 'django.contrib.staticfiles',
 'compressor',
 'compressor_toolkit',
 'corsheaders',
 'widget_tweaks',
 'easy_thumbnails',
 'filer',
 'mptt',
 'rules.apps.AutodiscoverRulesConfig']
Installed Middleware:
['corsheaders.middleware.CorsMiddleware',
 'django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.locale.LocaleMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']



Traceback:

File "/home/timo/job/integreat/django/.venv/lib/python3.7/site-packages/django/core/handlers/exception.py" in inner
  34.             response = get_response(request)

File "/home/timo/job/integreat/django/.venv/lib/python3.7/site-packages/django/core/handlers/base.py" in _get_response
  115.                 response = self.process_exception_by_middleware(e, request)

File "/home/timo/job/integreat/django/.venv/lib/python3.7/site-packages/django/core/handlers/base.py" in _get_response
  113.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "/home/timo/job/integreat/django/.venv/lib/python3.7/site-packages/django/views/generic/base.py" in view
  71.             return self.dispatch(request, *args, **kwargs)

File "/home/timo/job/integreat/django/.venv/lib/python3.7/site-packages/django/utils/decorators.py" in _wrapper
  45.         return bound_method(*args, **kwargs)

File "/home/timo/job/integreat/django/.venv/lib/python3.7/site-packages/django/contrib/auth/decorators.py" in _wrapped_view
  21.                 return view_func(request, *args, **kwargs)

File "/home/timo/job/integreat/django/.venv/lib/python3.7/site-packages/django/utils/decorators.py" in _wrapper
  45.         return bound_method(*args, **kwargs)

File "/home/timo/job/integreat/django/src/cms/decorators.py" in wrap
  53.             return function(request, *args, **kwargs)

File "/home/timo/job/integreat/django/.venv/lib/python3.7/site-packages/django/contrib/auth/mixins.py" in dispatch
  85.         return super().dispatch(request, *args, **kwargs)

File "/home/timo/job/integreat/django/.venv/lib/python3.7/site-packages/django/views/generic/base.py" in dispatch
  97.         return handler(request, *args, **kwargs)

File "/home/timo/job/integreat/django/src/cms/views/language_tree/language_tree_node_view.py" in post
  58.         if not language_tree_node_form.is_valid():

File "/home/timo/job/integreat/django/.venv/lib/python3.7/site-packages/django/forms/forms.py" in is_valid
  185.         return self.is_bound and not self.errors

File "/home/timo/job/integreat/django/.venv/lib/python3.7/site-packages/django/forms/forms.py" in errors
  180.             self.full_clean()

File "/home/timo/job/integreat/django/.venv/lib/python3.7/site-packages/django/forms/forms.py" in full_clean
  381.         self._clean_fields()

File "/home/timo/job/integreat/django/.venv/lib/python3.7/site-packages/django/forms/forms.py" in _clean_fields
  399.                     value = field.clean(value)

File "/home/timo/job/integreat/django/.venv/lib/python3.7/site-packages/django/forms/fields.py" in clean
  148.         value = self.to_python(value)

File "/home/timo/job/integreat/django/.venv/lib/python3.7/site-packages/django/forms/models.py" in to_python
  1248.             value = self.queryset.get(**{key: value})

File "/home/timo/job/integreat/django/.venv/lib/python3.7/site-packages/django/db/models/query.py" in get
  412.             (self.model._meta.object_name, num)

Exception Type: MultipleObjectsReturned at /augsburg/language-tree/4/edit
Exception Value: get() returned more than one LanguageTreeNode -- it returned 3!
</details>

I assume that this is a bug in the mptt library - TreeQuerySets don't seem to work properly with the `difference()`-method...

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `src/cms/forms/language_tree/language_tree_node_form.py`
Content:
```
1 import logging
2 
3 from django import forms
4 from django.utils.translation import ugettext_lazy as _
5 
6 from ...models import Language, LanguageTreeNode
7 
8 
9 logger = logging.getLogger(__name__)
10 
11 
12 class LanguageField(forms.ModelChoiceField):
13     """
14     Form field helper class to overwrite the label function (which would otherwise call __str__)
15     """
16 
17     def label_from_instance(self, obj):
18         return obj.translated_name
19 
20 
21 class LanguageTreeNodeForm(forms.ModelForm):
22     """
23     Form for creating and modifying language tree node objects
24     """
25 
26     class Meta:
27         model = LanguageTreeNode
28         fields = ["language", "parent", "active"]
29         field_classes = {
30             "language": LanguageField,
31             "parent": LanguageField,
32         }
33 
34     def __init__(self, *args, **kwargs):
35         logger.info(
36             "LanguageTreeNodeForm instantiated with data %s and instance %s",
37             kwargs.get("data"),
38             kwargs.get("instance"),
39         )
40 
41         # current region
42         region = kwargs.pop("region", None)
43 
44         super().__init__(*args, **kwargs)
45 
46         parent_queryset = region.language_tree_nodes
47         excluded_languages = region.languages.exclude(language_tree_nodes=self.instance)
48 
49         if self.instance.id:
50             children = self.instance.get_descendants(include_self=True)
51             parent_queryset = parent_queryset.difference(children)
52         else:
53             self.instance.region = region
54 
55         # limit possible parents to nodes of current region
56         self.fields["parent"].queryset = parent_queryset
57         # limit possible languages to those which are not yet included in the tree
58         self.fields["language"].queryset = Language.objects.exclude(
59             id__in=excluded_languages
60         )
61 
62     def save(self, commit=True):
63         """
64         Function to create or update a language tree node
65         """
66         logger.info(
67             "LanguageTreeNodeForm saved with cleaned data %s and changed data %s",
68             self.cleaned_data,
69             self.changed_data,
70         )
71 
72         return super().save(commit=commit)
73 
74     def clean(self):
75         """
76         Don't allow multiple root nodes for one region:
77             If self is a root node and the region already has a default language,
78             raise a validation error.
79         """
80         cleaned_data = super().clean()
81         logger.info("LanguageTreeNodeForm cleaned with cleaned data %s", cleaned_data)
82         default_language = self.instance.region.default_language
83         # There are two cases in which this error is thrown.
84         # Both cases include that the parent field is None.
85         # 1. The instance does exist:
86         #   - The default language is different from the instance language
87         # 2. The instance does not exist:
88         #   - The default language exists
89         if not cleaned_data.get("parent") and (
90             (self.instance.id and default_language != self.instance.language)
91             or (not self.instance.id and default_language)
92         ):
93             self.add_error(
94                 "parent",
95                 forms.ValidationError(
96                     _(
97                         "This region has already a default language."
98                         "Please specify a source language for this language."
99                     ),
100                     code="invalid",
101                 ),
102             )
103
```
--- 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/src/cms/forms/language_tree/language_tree_node_form.py b/src/cms/forms/language_tree/language_tree_node_form.py
--- a/src/cms/forms/language_tree/language_tree_node_form.py
+++ b/src/cms/forms/language_tree/language_tree_node_form.py
@@ -48,7 +48,7 @@
 
         if self.instance.id:
             children = self.instance.get_descendants(include_self=True)
-            parent_queryset = parent_queryset.difference(children)
+            parent_queryset = parent_queryset.exclude(id__in=children)
         else:
             self.instance.region = region

{"golden_diff": "diff --git a/src/cms/forms/language_tree/language_tree_node_form.py b/src/cms/forms/language_tree/language_tree_node_form.py\n--- a/src/cms/forms/language_tree/language_tree_node_form.py\n+++ b/src/cms/forms/language_tree/language_tree_node_form.py\n@@ -48,7 +48,7 @@\n \n         if self.instance.id:\n             children = self.instance.get_descendants(include_self=True)\n-            parent_queryset = parent_queryset.difference(children)\n+            parent_queryset = parent_queryset.exclude(id__in=children)\n         else:\n             self.instance.region = region\n", "issue": "Language tree node form not working\n### Describe the Bug\r\n<!-- A clear and concise description of what the bug is. -->\r\nSince commit 928dec60b79ba47366099ca4227b2abe0acb2de7, the language node form is not working anymore.\r\n\r\n### Steps to Reproduce\r\n\r\n1. Go to a region\r\n2. Open language tree\r\n3. Open language tree node\r\n4. Click on save\r\n\r\n### Expected Behavior\r\n<!-- A clear and concise description of what you expected to happen. -->\r\nThe language tree node should be saved\r\n\r\n### Actual Behavior\r\n<!-- A clear and concise description of what actually happened. -->\r\nthe following error appears:\r\n```\r\nMultipleObjectsReturned at /augsburg/language-tree/4/edit\r\n\r\nget() returned more than one LanguageTreeNode -- it returned 3!\r\n```\r\n### Additional Information\r\n<!-- Add any other context (e.g. logs, screenshots, etc.) about the problem here. -->\r\n<details>\r\n  <summary>Debug Stacktrace</summary>\r\n\r\n\r\nEnvironment:\r\n\r\n\r\nRequest Method: POST\r\nRequest URL: http://localhost:8000/augsburg/language-tree/4/edit\r\n\r\nDjango Version: 2.2.16\r\nPython Version: 3.7.9\r\nInstalled Applications:\r\n['cms.apps.CmsConfig',\r\n 'gvz_api.apps.GvzApiConfig',\r\n 'django.contrib.admin',\r\n 'django.contrib.auth',\r\n 'django.contrib.contenttypes',\r\n 'django.contrib.messages',\r\n 'django.contrib.sessions',\r\n 'django.contrib.sitemaps',\r\n 'django.contrib.staticfiles',\r\n 'compressor',\r\n 'compressor_toolkit',\r\n 'corsheaders',\r\n 'widget_tweaks',\r\n 'easy_thumbnails',\r\n 'filer',\r\n 'mptt',\r\n 'rules.apps.AutodiscoverRulesConfig']\r\nInstalled Middleware:\r\n['corsheaders.middleware.CorsMiddleware',\r\n 'django.middleware.security.SecurityMiddleware',\r\n 'django.contrib.sessions.middleware.SessionMiddleware',\r\n 'django.middleware.locale.LocaleMiddleware',\r\n 'django.middleware.common.CommonMiddleware',\r\n 'django.middleware.csrf.CsrfViewMiddleware',\r\n 'django.contrib.auth.middleware.AuthenticationMiddleware',\r\n 'django.contrib.messages.middleware.MessageMiddleware',\r\n 'django.middleware.clickjacking.XFrameOptionsMiddleware']\r\n\r\n\r\n\r\nTraceback:\r\n\r\nFile \"/home/timo/job/integreat/django/.venv/lib/python3.7/site-packages/django/core/handlers/exception.py\" in inner\r\n  34.             response = get_response(request)\r\n\r\nFile \"/home/timo/job/integreat/django/.venv/lib/python3.7/site-packages/django/core/handlers/base.py\" in _get_response\r\n  115.                 response = self.process_exception_by_middleware(e, request)\r\n\r\nFile \"/home/timo/job/integreat/django/.venv/lib/python3.7/site-packages/django/core/handlers/base.py\" in _get_response\r\n  113.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)\r\n\r\nFile \"/home/timo/job/integreat/django/.venv/lib/python3.7/site-packages/django/views/generic/base.py\" in view\r\n  71.             return self.dispatch(request, *args, **kwargs)\r\n\r\nFile \"/home/timo/job/integreat/django/.venv/lib/python3.7/site-packages/django/utils/decorators.py\" in _wrapper\r\n  45.         return bound_method(*args, **kwargs)\r\n\r\nFile \"/home/timo/job/integreat/django/.venv/lib/python3.7/site-packages/django/contrib/auth/decorators.py\" in _wrapped_view\r\n  21.                 return view_func(request, *args, **kwargs)\r\n\r\nFile \"/home/timo/job/integreat/django/.venv/lib/python3.7/site-packages/django/utils/decorators.py\" in _wrapper\r\n  45.         return bound_method(*args, **kwargs)\r\n\r\nFile \"/home/timo/job/integreat/django/src/cms/decorators.py\" in wrap\r\n  53.             return function(request, *args, **kwargs)\r\n\r\nFile \"/home/timo/job/integreat/django/.venv/lib/python3.7/site-packages/django/contrib/auth/mixins.py\" in dispatch\r\n  85.         return super().dispatch(request, *args, **kwargs)\r\n\r\nFile \"/home/timo/job/integreat/django/.venv/lib/python3.7/site-packages/django/views/generic/base.py\" in dispatch\r\n  97.         return handler(request, *args, **kwargs)\r\n\r\nFile \"/home/timo/job/integreat/django/src/cms/views/language_tree/language_tree_node_view.py\" in post\r\n  58.         if not language_tree_node_form.is_valid():\r\n\r\nFile \"/home/timo/job/integreat/django/.venv/lib/python3.7/site-packages/django/forms/forms.py\" in is_valid\r\n  185.         return self.is_bound and not self.errors\r\n\r\nFile \"/home/timo/job/integreat/django/.venv/lib/python3.7/site-packages/django/forms/forms.py\" in errors\r\n  180.             self.full_clean()\r\n\r\nFile \"/home/timo/job/integreat/django/.venv/lib/python3.7/site-packages/django/forms/forms.py\" in full_clean\r\n  381.         self._clean_fields()\r\n\r\nFile \"/home/timo/job/integreat/django/.venv/lib/python3.7/site-packages/django/forms/forms.py\" in _clean_fields\r\n  399.                     value = field.clean(value)\r\n\r\nFile \"/home/timo/job/integreat/django/.venv/lib/python3.7/site-packages/django/forms/fields.py\" in clean\r\n  148.         value = self.to_python(value)\r\n\r\nFile \"/home/timo/job/integreat/django/.venv/lib/python3.7/site-packages/django/forms/models.py\" in to_python\r\n  1248.             value = self.queryset.get(**{key: value})\r\n\r\nFile \"/home/timo/job/integreat/django/.venv/lib/python3.7/site-packages/django/db/models/query.py\" in get\r\n  412.             (self.model._meta.object_name, num)\r\n\r\nException Type: MultipleObjectsReturned at /augsburg/language-tree/4/edit\r\nException Value: get() returned more than one LanguageTreeNode -- it returned 3!\r\n</details>\r\n\r\nI assume that this is a bug in the mptt library - TreeQuerySets don't seem to work properly with the `difference()`-method...\nLanguage tree node form not working\n### Describe the Bug\r\n<!-- A clear and concise description of what the bug is. -->\r\nSince commit 928dec60b79ba47366099ca4227b2abe0acb2de7, the language node form is not working anymore.\r\n\r\n### Steps to Reproduce\r\n\r\n1. Go to a region\r\n2. Open language tree\r\n3. Open language tree node\r\n4. Click on save\r\n\r\n### Expected Behavior\r\n<!-- A clear and concise description of what you expected to happen. -->\r\nThe language tree node should be saved\r\n\r\n### Actual Behavior\r\n<!-- A clear and concise description of what actually happened. -->\r\nthe following error appears:\r\n```\r\nMultipleObjectsReturned at /augsburg/language-tree/4/edit\r\n\r\nget() returned more than one LanguageTreeNode -- it returned 3!\r\n```\r\n### Additional Information\r\n<!-- Add any other context (e.g. logs, screenshots, etc.) about the problem here. -->\r\n<details>\r\n  <summary>Debug Stacktrace</summary>\r\n\r\n\r\nEnvironment:\r\n\r\n\r\nRequest Method: POST\r\nRequest URL: http://localhost:8000/augsburg/language-tree/4/edit\r\n\r\nDjango Version: 2.2.16\r\nPython Version: 3.7.9\r\nInstalled Applications:\r\n['cms.apps.CmsConfig',\r\n 'gvz_api.apps.GvzApiConfig',\r\n 'django.contrib.admin',\r\n 'django.contrib.auth',\r\n 'django.contrib.contenttypes',\r\n 'django.contrib.messages',\r\n 'django.contrib.sessions',\r\n 'django.contrib.sitemaps',\r\n 'django.contrib.staticfiles',\r\n 'compressor',\r\n 'compressor_toolkit',\r\n 'corsheaders',\r\n 'widget_tweaks',\r\n 'easy_thumbnails',\r\n 'filer',\r\n 'mptt',\r\n 'rules.apps.AutodiscoverRulesConfig']\r\nInstalled Middleware:\r\n['corsheaders.middleware.CorsMiddleware',\r\n 'django.middleware.security.SecurityMiddleware',\r\n 'django.contrib.sessions.middleware.SessionMiddleware',\r\n 'django.middleware.locale.LocaleMiddleware',\r\n 'django.middleware.common.CommonMiddleware',\r\n 'django.middleware.csrf.CsrfViewMiddleware',\r\n 'django.contrib.auth.middleware.AuthenticationMiddleware',\r\n 'django.contrib.messages.middleware.MessageMiddleware',\r\n 'django.middleware.clickjacking.XFrameOptionsMiddleware']\r\n\r\n\r\n\r\nTraceback:\r\n\r\nFile \"/home/timo/job/integreat/django/.venv/lib/python3.7/site-packages/django/core/handlers/exception.py\" in inner\r\n  34.             response = get_response(request)\r\n\r\nFile \"/home/timo/job/integreat/django/.venv/lib/python3.7/site-packages/django/core/handlers/base.py\" in _get_response\r\n  115.                 response = self.process_exception_by_middleware(e, request)\r\n\r\nFile \"/home/timo/job/integreat/django/.venv/lib/python3.7/site-packages/django/core/handlers/base.py\" in _get_response\r\n  113.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)\r\n\r\nFile \"/home/timo/job/integreat/django/.venv/lib/python3.7/site-packages/django/views/generic/base.py\" in view\r\n  71.             return self.dispatch(request, *args, **kwargs)\r\n\r\nFile \"/home/timo/job/integreat/django/.venv/lib/python3.7/site-packages/django/utils/decorators.py\" in _wrapper\r\n  45.         return bound_method(*args, **kwargs)\r\n\r\nFile \"/home/timo/job/integreat/django/.venv/lib/python3.7/site-packages/django/contrib/auth/decorators.py\" in _wrapped_view\r\n  21.                 return view_func(request, *args, **kwargs)\r\n\r\nFile \"/home/timo/job/integreat/django/.venv/lib/python3.7/site-packages/django/utils/decorators.py\" in _wrapper\r\n  45.         return bound_method(*args, **kwargs)\r\n\r\nFile \"/home/timo/job/integreat/django/src/cms/decorators.py\" in wrap\r\n  53.             return function(request, *args, **kwargs)\r\n\r\nFile \"/home/timo/job/integreat/django/.venv/lib/python3.7/site-packages/django/contrib/auth/mixins.py\" in dispatch\r\n  85.         return super().dispatch(request, *args, **kwargs)\r\n\r\nFile \"/home/timo/job/integreat/django/.venv/lib/python3.7/site-packages/django/views/generic/base.py\" in dispatch\r\n  97.         return handler(request, *args, **kwargs)\r\n\r\nFile \"/home/timo/job/integreat/django/src/cms/views/language_tree/language_tree_node_view.py\" in post\r\n  58.         if not language_tree_node_form.is_valid():\r\n\r\nFile \"/home/timo/job/integreat/django/.venv/lib/python3.7/site-packages/django/forms/forms.py\" in is_valid\r\n  185.         return self.is_bound and not self.errors\r\n\r\nFile \"/home/timo/job/integreat/django/.venv/lib/python3.7/site-packages/django/forms/forms.py\" in errors\r\n  180.             self.full_clean()\r\n\r\nFile \"/home/timo/job/integreat/django/.venv/lib/python3.7/site-packages/django/forms/forms.py\" in full_clean\r\n  381.         self._clean_fields()\r\n\r\nFile \"/home/timo/job/integreat/django/.venv/lib/python3.7/site-packages/django/forms/forms.py\" in _clean_fields\r\n  399.                     value = field.clean(value)\r\n\r\nFile \"/home/timo/job/integreat/django/.venv/lib/python3.7/site-packages/django/forms/fields.py\" in clean\r\n  148.         value = self.to_python(value)\r\n\r\nFile \"/home/timo/job/integreat/django/.venv/lib/python3.7/site-packages/django/forms/models.py\" in to_python\r\n  1248.             value = self.queryset.get(**{key: value})\r\n\r\nFile \"/home/timo/job/integreat/django/.venv/lib/python3.7/site-packages/django/db/models/query.py\" in get\r\n  412.             (self.model._meta.object_name, num)\r\n\r\nException Type: MultipleObjectsReturned at /augsburg/language-tree/4/edit\r\nException Value: get() returned more than one LanguageTreeNode -- it returned 3!\r\n</details>\r\n\r\nI assume that this is a bug in the mptt library - TreeQuerySets don't seem to work properly with the `difference()`-method...\n", "before_files": [{"content": "import logging\n\nfrom django import forms\nfrom django.utils.translation import ugettext_lazy as _\n\nfrom ...models import Language, LanguageTreeNode\n\n\nlogger = logging.getLogger(__name__)\n\n\nclass LanguageField(forms.ModelChoiceField):\n    \"\"\"\n    Form field helper class to overwrite the label function (which would otherwise call __str__)\n    \"\"\"\n\n    def label_from_instance(self, obj):\n        return obj.translated_name\n\n\nclass LanguageTreeNodeForm(forms.ModelForm):\n    \"\"\"\n    Form for creating and modifying language tree node objects\n    \"\"\"\n\n    class Meta:\n        model = LanguageTreeNode\n        fields = [\"language\", \"parent\", \"active\"]\n        field_classes = {\n            \"language\": LanguageField,\n            \"parent\": LanguageField,\n        }\n\n    def __init__(self, *args, **kwargs):\n        logger.info(\n            \"LanguageTreeNodeForm instantiated with data %s and instance %s\",\n            kwargs.get(\"data\"),\n            kwargs.get(\"instance\"),\n        )\n\n        # current region\n        region = kwargs.pop(\"region\", None)\n\n        super().__init__(*args, **kwargs)\n\n        parent_queryset = region.language_tree_nodes\n        excluded_languages = region.languages.exclude(language_tree_nodes=self.instance)\n\n        if self.instance.id:\n            children = self.instance.get_descendants(include_self=True)\n            parent_queryset = parent_queryset.difference(children)\n        else:\n            self.instance.region = region\n\n        # limit possible parents to nodes of current region\n        self.fields[\"parent\"].queryset = parent_queryset\n        # limit possible languages to those which are not yet included in the tree\n        self.fields[\"language\"].queryset = Language.objects.exclude(\n            id__in=excluded_languages\n        )\n\n    def save(self, commit=True):\n        \"\"\"\n        Function to create or update a language tree node\n        \"\"\"\n        logger.info(\n            \"LanguageTreeNodeForm saved with cleaned data %s and changed data %s\",\n            self.cleaned_data,\n            self.changed_data,\n        )\n\n        return super().save(commit=commit)\n\n    def clean(self):\n        \"\"\"\n        Don't allow multiple root nodes for one region:\n            If self is a root node and the region already has a default language,\n            raise a validation error.\n        \"\"\"\n        cleaned_data = super().clean()\n        logger.info(\"LanguageTreeNodeForm cleaned with cleaned data %s\", cleaned_data)\n        default_language = self.instance.region.default_language\n        # There are two cases in which this error is thrown.\n        # Both cases include that the parent field is None.\n        # 1. The instance does exist:\n        #   - The default language is different from the instance language\n        # 2. The instance does not exist:\n        #   - The default language exists\n        if not cleaned_data.get(\"parent\") and (\n            (self.instance.id and default_language != self.instance.language)\n            or (not self.instance.id and default_language)\n        ):\n            self.add_error(\n                \"parent\",\n                forms.ValidationError(\n                    _(\n                        \"This region has already a default language.\"\n                        \"Please specify a source language for this language.\"\n                    ),\n                    code=\"invalid\",\n                ),\n            )\n", "path": "src/cms/forms/language_tree/language_tree_node_form.py"}], "after_files": [{"content": "import logging\n\nfrom django import forms\nfrom django.utils.translation import ugettext_lazy as _\n\nfrom ...models import Language, LanguageTreeNode\n\n\nlogger = logging.getLogger(__name__)\n\n\nclass LanguageField(forms.ModelChoiceField):\n    \"\"\"\n    Form field helper class to overwrite the label function (which would otherwise call __str__)\n    \"\"\"\n\n    def label_from_instance(self, obj):\n        return obj.translated_name\n\n\nclass LanguageTreeNodeForm(forms.ModelForm):\n    \"\"\"\n    Form for creating and modifying language tree node objects\n    \"\"\"\n\n    class Meta:\n        model = LanguageTreeNode\n        fields = [\"language\", \"parent\", \"active\"]\n        field_classes = {\n            \"language\": LanguageField,\n            \"parent\": LanguageField,\n        }\n\n    def __init__(self, *args, **kwargs):\n        logger.info(\n            \"LanguageTreeNodeForm instantiated with data %s and instance %s\",\n            kwargs.get(\"data\"),\n            kwargs.get(\"instance\"),\n        )\n\n        # current region\n        region = kwargs.pop(\"region\", None)\n\n        super().__init__(*args, **kwargs)\n\n        parent_queryset = region.language_tree_nodes\n        excluded_languages = region.languages.exclude(language_tree_nodes=self.instance)\n\n        if self.instance.id:\n            children = self.instance.get_descendants(include_self=True)\n            parent_queryset = parent_queryset.exclude(id__in=children)\n        else:\n            self.instance.region = region\n\n        # limit possible parents to nodes of current region\n        self.fields[\"parent\"].queryset = parent_queryset\n        # limit possible languages to those which are not yet included in the tree\n        self.fields[\"language\"].queryset = Language.objects.exclude(\n            id__in=excluded_languages\n        )\n\n    def save(self, commit=True):\n        \"\"\"\n        Function to create or update a language tree node\n        \"\"\"\n        logger.info(\n            \"LanguageTreeNodeForm saved with cleaned data %s and changed data %s\",\n            self.cleaned_data,\n            self.changed_data,\n        )\n\n        return super().save(commit=commit)\n\n    def clean(self):\n        \"\"\"\n        Don't allow multiple root nodes for one region:\n            If self is a root node and the region already has a default language,\n            raise a validation error.\n        \"\"\"\n        cleaned_data = super().clean()\n        logger.info(\"LanguageTreeNodeForm cleaned with cleaned data %s\", cleaned_data)\n        default_language = self.instance.region.default_language\n        # There are two cases in which this error is thrown.\n        # Both cases include that the parent field is None.\n        # 1. The instance does exist:\n        #   - The default language is different from the instance language\n        # 2. The instance does not exist:\n        #   - The default language exists\n        if not cleaned_data.get(\"parent\") and (\n            (self.instance.id and default_language != self.instance.language)\n            or (not self.instance.id and default_language)\n        ):\n            self.add_error(\n                \"parent\",\n                forms.ValidationError(\n                    _(\n                        \"This region has already a default language.\"\n                        \"Please specify a source language for this language.\"\n                    ),\n                    code=\"invalid\",\n                ),\n            )\n", "path": "src/cms/forms/language_tree/language_tree_node_form.py"}]}