We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
List of reports not loading for some users
The reports page fetches user information from `/rest/v1/user/{id}` and this seems to be failing when the Country name of primary organisation is unicode. 

Created via Reamaze:

Link: https://akvoo.reamaze.com/admin/conversations/list-of-reports-not-loading




--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `akvo/rest/views/user.py`
Content:
```
1 # -*- coding: utf-8 -*-
2 """Akvo RSR is covered by the GNU Affero General Public License.
3 
4 See more details in the license.txt file located at the root folder of the Akvo RSR module.
5 For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >.
6 """
7 
8 from django.contrib.auth import get_user_model
9 from django.db import IntegrityError
10 from django.utils.translation import ugettext_lazy as _
11 
12 from rest_framework import status
13 from rest_framework.authentication import SessionAuthentication
14 from rest_framework.decorators import api_view
15 from rest_framework.decorators import authentication_classes
16 from rest_framework.exceptions import PermissionDenied
17 from rest_framework.response import Response
18 
19 from akvo.rest.models import TastyTokenAuthentication
20 from ...rsr.models import Employment
21 from ...rsr.models import Organisation
22 from ..viewsets import BaseRSRViewSet
23 from ..serializers import EmploymentSerializer
24 from ..serializers import OrganisationSerializer
25 from ..serializers import UserSerializer, UserDetailsSerializer, UserPasswordSerializer
26 
27 
28 class UserViewSet(BaseRSRViewSet):
29 
30     """User resource."""
31 
32     queryset = get_user_model().objects.select_related(
33         'organisation',
34         'organisation__primary_location',
35         'organisation__primary_location__country',
36         'organisation__primary_location__location_target',
37         'organisation__primary_location__location_target__internal_org_ids',
38     ).prefetch_related(
39         'organisations',
40         'organisations__primary_location',
41         'organisations__primary_location__country',
42         'organisations__primary_location__location_target',)
43     serializer_class = UserSerializer
44 
45 
46 @api_view(['POST'])
47 def change_password(request, pk=None):
48     # Get the user, or return an error if the user does not exist
49     try:
50         user = get_user_model().objects.get(pk=pk)
51     except get_user_model().DoesNotExist:
52         return Response({'user': _('User does not exist')}, status=status.HTTP_400_BAD_REQUEST)
53 
54     # Users are only allowed to edit their own details
55     request_user = getattr(request, 'user', None)
56     if not user == request_user:
57         raise PermissionDenied()
58 
59     # Process request
60     serializer = UserPasswordSerializer(data=request.data, instance=user)
61     if serializer.is_valid():
62         user = serializer.update(serializer.instance, serializer.validated_data)
63         user.save()
64         return Response({'status': 'password set'})
65     else:
66         return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
67 
68 
69 @api_view(['POST'])
70 def update_details(request, pk=None):
71     # Get the user, or return an error if the user does not exist
72     try:
73         user = get_user_model().objects.get(pk=pk)
74     except get_user_model().DoesNotExist:
75         return Response({'user': _('User does not exist')}, status=status.HTTP_400_BAD_REQUEST)
76 
77     # Users are only allowed to edit their own details
78     request_user = getattr(request, 'user', None)
79     if not user == request_user:
80         raise PermissionDenied()
81 
82     # Process request
83     serializer = UserDetailsSerializer(data=request.data)
84     if serializer.is_valid():
85         serializer.update(user, serializer.initial_data)
86         return Response(request.data)
87     else:
88         return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
89 
90 
91 @api_view(['POST'])
92 @authentication_classes([SessionAuthentication, TastyTokenAuthentication])
93 def request_organisation(request, pk=None):
94 
95     # Add missing keys to request.data to simplify code and getting working
96     # with DRF-3 Serializer
97     for key in ('group', 'country', 'job_title'):
98         if key not in request.data:
99             request.data[key] = ''
100 
101     # Get the user, or return an error if the user does not exist
102     try:
103         user_by_pk = get_user_model().objects.get(pk=pk)
104     except get_user_model().DoesNotExist:
105         return Response({'user': _('User does not exist')}, status=status.HTTP_400_BAD_REQUEST)
106 
107     # request.user is the user identified by the auth token
108     user = request.user
109     # Users themselves are only allowed to request to join an organisation
110     if not user_by_pk == user:
111         raise PermissionDenied()
112     request.data['user'] = pk
113 
114     # Process request
115     serializer = EmploymentSerializer(data=request.data)
116     if serializer.is_valid():
117         try:
118             organisation = Organisation.objects.get(pk=serializer.data['organisation'])
119             employment = Employment.objects.create(
120                 user=user,
121                 organisation=organisation,
122                 country=serializer.data['country'],
123                 job_title=serializer.data['job_title'],
124                 is_approved=False,
125             )
126         except IntegrityError:
127             return Response({'detail': _(u'User already linked to this organisation')},
128                             status=status.HTTP_409_CONFLICT)
129 
130         data = EmploymentSerializer(employment).data
131         if data['country']:
132             data['country_full'] = employment.iati_country().name
133             data['country_name'] = str(employment.iati_country())
134         else:
135             data['country_full'] = ''
136         data['organisation_full'] = OrganisationSerializer(organisation).data
137         data['id'] = employment.pk
138 
139         return Response(data)
140     else:
141         return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
142
```

Path: `akvo/rsr/models/employment.py`
Content:
```
1 # -*- coding: utf-8 -*-
2 
3 # Akvo RSR is covered by the GNU Affero General Public License.
4 # See more details in the license.txt file located at the root folder of the Akvo RSR module.
5 # For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >.
6 
7 from akvo.codelists import models as codelist_models
8 from akvo.codelists.store.codelists_v202 import COUNTRY
9 from akvo.utils import codelist_choices, codelist_value
10 
11 from django.contrib.admin.models import LogEntry, CHANGE
12 from django.contrib.auth import get_user_model
13 from django.contrib.auth.models import Group
14 from django.contrib.contenttypes.models import ContentType
15 from django.core.exceptions import ObjectDoesNotExist
16 from django.db import models
17 from django.db.models.query import QuerySet as DjangoQuerySet
18 from django.forms.models import model_to_dict
19 from django.utils.encoding import force_unicode
20 from django.utils.translation import ugettext_lazy as _
21 
22 from .models_utils import QuerySetManager
23 
24 from ..fields import ValidXMLCharField
25 
26 
27 class Employment(models.Model):
28     organisation = models.ForeignKey('Organisation', verbose_name=_(u'organisation'),
29                                      related_name='employees')
30     user = models.ForeignKey('User', verbose_name=_(u'user'), related_name='employers')
31     group = models.ForeignKey(Group, verbose_name=_(u'group'), null=True,
32                               related_name='employments', related_query_name='employment',
33                               on_delete=models.SET_NULL,
34                               help_text=_('The permissions group for this user\'s employment.'))
35     is_approved = models.BooleanField(_('approved'), default=False,
36                                       help_text=_('Designates whether this employment is approved '
37                                                   'by an administrator.'))
38     country = ValidXMLCharField(
39         _(u'country'), blank=True, max_length=2, choices=codelist_choices(COUNTRY, show_code=False)
40     )
41     job_title = ValidXMLCharField(_(u'job title'), max_length=50, blank=True)
42 
43     objects = QuerySetManager()
44 
45     class QuerySet(DjangoQuerySet):
46         def organisations(self):
47             """
48             Return an Organisation QuerySet containing the organisations of the Employment QuerySet
49             """
50             from ..models import Organisation
51             return Organisation.objects.filter(employees__in=self).distinct()
52 
53         def users(self):
54             """
55             Return a User QuerySet containing the users of the Employment QuerySet
56             """
57             return get_user_model().objects.filter(employers__in=self).distinct()
58 
59         def approved(self):
60             """
61             Return an Employment QuerySet containing the approved Employments
62             """
63             return self.filter(is_approved=True)
64 
65     class Meta:
66         app_label = 'rsr'
67         verbose_name = _(u'user employment')
68         verbose_name_plural = _(u'user employments')
69         unique_together = ('organisation', 'user', 'group')
70 
71     def __unicode__(self):
72         return u"{0} {1}: {2}".format(self.user.first_name, self.user.last_name,
73                                       self.organisation.name)
74 
75     def iati_country(self):
76         return codelist_value(codelist_models.Country, self, 'country')
77 
78     def iati_country_unicode(self):
79         return str(self.iati_country())
80 
81     def approve(self, approved_by):
82         """
83         Approve an Employment. Will also be logged in the Employment admin history.
84 
85         :param approved_by: User that approves the Employment
86         """
87         if not self.is_approved:
88             self.is_approved = True
89             self.save()
90 
91             # Log in Employment admin history
92             LogEntry.objects.log_action(
93                 user_id=approved_by.pk,
94                 content_type_id=ContentType.objects.get_for_model(self).pk,
95                 object_id=self.pk,
96                 object_repr=force_unicode(self),
97                 action_flag=CHANGE,
98                 change_message=u'Changed is_approved, outside of admin.'
99             )
100 
101     def to_dict(self, org_list):
102         # Set groups in right order
103         all_groups = []
104         auth_group_names = ['Users', 'User Managers', 'Project Editors', 'Admins']
105         for auth_group_name in auth_group_names:
106             try:
107                 all_groups.append(Group.objects.get(name=auth_group_name))
108             except ObjectDoesNotExist:
109                 continue
110 
111         user_group = model_to_dict(self.group, fields=['id', 'name']) if self.group else None
112         other_groups = [model_to_dict(group, fields=['id', 'name']) for group in all_groups]
113 
114         return dict(
115             id=self.pk,
116             organisation_full=model_to_dict(self.organisation, fields=['id', 'name', 'long_name', ]),
117             user_full=model_to_dict(self.user, fields=['id', 'first_name', 'last_name', 'email', ]),
118             is_approved=self.is_approved,
119             job_title=self.job_title,
120             country_full=self.iati_country().name if self.country else '',
121             group=user_group,
122             other_groups=other_groups,
123             actions=True if self.organisation in org_list else False,
124         )
125
```
--- 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/akvo/rest/views/user.py b/akvo/rest/views/user.py
--- a/akvo/rest/views/user.py
+++ b/akvo/rest/views/user.py
@@ -130,7 +130,7 @@
         data = EmploymentSerializer(employment).data
         if data['country']:
             data['country_full'] = employment.iati_country().name
-            data['country_name'] = str(employment.iati_country())
+            data['country_name'] = unicode(employment.iati_country())
         else:
             data['country_full'] = ''
         data['organisation_full'] = OrganisationSerializer(organisation).data
diff --git a/akvo/rsr/models/employment.py b/akvo/rsr/models/employment.py
--- a/akvo/rsr/models/employment.py
+++ b/akvo/rsr/models/employment.py
@@ -76,7 +76,7 @@
         return codelist_value(codelist_models.Country, self, 'country')
 
     def iati_country_unicode(self):
-        return str(self.iati_country())
+        return unicode(self.iati_country())
 
     def approve(self, approved_by):
         """

{"golden_diff": "diff --git a/akvo/rest/views/user.py b/akvo/rest/views/user.py\n--- a/akvo/rest/views/user.py\n+++ b/akvo/rest/views/user.py\n@@ -130,7 +130,7 @@\n         data = EmploymentSerializer(employment).data\n         if data['country']:\n             data['country_full'] = employment.iati_country().name\n-            data['country_name'] = str(employment.iati_country())\n+            data['country_name'] = unicode(employment.iati_country())\n         else:\n             data['country_full'] = ''\n         data['organisation_full'] = OrganisationSerializer(organisation).data\ndiff --git a/akvo/rsr/models/employment.py b/akvo/rsr/models/employment.py\n--- a/akvo/rsr/models/employment.py\n+++ b/akvo/rsr/models/employment.py\n@@ -76,7 +76,7 @@\n         return codelist_value(codelist_models.Country, self, 'country')\n \n     def iati_country_unicode(self):\n-        return str(self.iati_country())\n+        return unicode(self.iati_country())\n \n     def approve(self, approved_by):\n         \"\"\"\n", "issue": "List of reports not loading for some users\nThe reports page fetches user information from `/rest/v1/user/{id}` and this seems to be failing when the Country name of primary organisation is unicode. \r\n\r\nCreated via Reamaze:\r\n\r\nLink: https://akvoo.reamaze.com/admin/conversations/list-of-reports-not-loading\r\n\r\n\r\n\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\n\"\"\"Akvo RSR is covered by the GNU Affero General Public License.\n\nSee more details in the license.txt file located at the root folder of the Akvo RSR module.\nFor additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >.\n\"\"\"\n\nfrom django.contrib.auth import get_user_model\nfrom django.db import IntegrityError\nfrom django.utils.translation import ugettext_lazy as _\n\nfrom rest_framework import status\nfrom rest_framework.authentication import SessionAuthentication\nfrom rest_framework.decorators import api_view\nfrom rest_framework.decorators import authentication_classes\nfrom rest_framework.exceptions import PermissionDenied\nfrom rest_framework.response import Response\n\nfrom akvo.rest.models import TastyTokenAuthentication\nfrom ...rsr.models import Employment\nfrom ...rsr.models import Organisation\nfrom ..viewsets import BaseRSRViewSet\nfrom ..serializers import EmploymentSerializer\nfrom ..serializers import OrganisationSerializer\nfrom ..serializers import UserSerializer, UserDetailsSerializer, UserPasswordSerializer\n\n\nclass UserViewSet(BaseRSRViewSet):\n\n    \"\"\"User resource.\"\"\"\n\n    queryset = get_user_model().objects.select_related(\n        'organisation',\n        'organisation__primary_location',\n        'organisation__primary_location__country',\n        'organisation__primary_location__location_target',\n        'organisation__primary_location__location_target__internal_org_ids',\n    ).prefetch_related(\n        'organisations',\n        'organisations__primary_location',\n        'organisations__primary_location__country',\n        'organisations__primary_location__location_target',)\n    serializer_class = UserSerializer\n\n\n@api_view(['POST'])\ndef change_password(request, pk=None):\n    # Get the user, or return an error if the user does not exist\n    try:\n        user = get_user_model().objects.get(pk=pk)\n    except get_user_model().DoesNotExist:\n        return Response({'user': _('User does not exist')}, status=status.HTTP_400_BAD_REQUEST)\n\n    # Users are only allowed to edit their own details\n    request_user = getattr(request, 'user', None)\n    if not user == request_user:\n        raise PermissionDenied()\n\n    # Process request\n    serializer = UserPasswordSerializer(data=request.data, instance=user)\n    if serializer.is_valid():\n        user = serializer.update(serializer.instance, serializer.validated_data)\n        user.save()\n        return Response({'status': 'password set'})\n    else:\n        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)\n\n\n@api_view(['POST'])\ndef update_details(request, pk=None):\n    # Get the user, or return an error if the user does not exist\n    try:\n        user = get_user_model().objects.get(pk=pk)\n    except get_user_model().DoesNotExist:\n        return Response({'user': _('User does not exist')}, status=status.HTTP_400_BAD_REQUEST)\n\n    # Users are only allowed to edit their own details\n    request_user = getattr(request, 'user', None)\n    if not user == request_user:\n        raise PermissionDenied()\n\n    # Process request\n    serializer = UserDetailsSerializer(data=request.data)\n    if serializer.is_valid():\n        serializer.update(user, serializer.initial_data)\n        return Response(request.data)\n    else:\n        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)\n\n\n@api_view(['POST'])\n@authentication_classes([SessionAuthentication, TastyTokenAuthentication])\ndef request_organisation(request, pk=None):\n\n    # Add missing keys to request.data to simplify code and getting working\n    # with DRF-3 Serializer\n    for key in ('group', 'country', 'job_title'):\n        if key not in request.data:\n            request.data[key] = ''\n\n    # Get the user, or return an error if the user does not exist\n    try:\n        user_by_pk = get_user_model().objects.get(pk=pk)\n    except get_user_model().DoesNotExist:\n        return Response({'user': _('User does not exist')}, status=status.HTTP_400_BAD_REQUEST)\n\n    # request.user is the user identified by the auth token\n    user = request.user\n    # Users themselves are only allowed to request to join an organisation\n    if not user_by_pk == user:\n        raise PermissionDenied()\n    request.data['user'] = pk\n\n    # Process request\n    serializer = EmploymentSerializer(data=request.data)\n    if serializer.is_valid():\n        try:\n            organisation = Organisation.objects.get(pk=serializer.data['organisation'])\n            employment = Employment.objects.create(\n                user=user,\n                organisation=organisation,\n                country=serializer.data['country'],\n                job_title=serializer.data['job_title'],\n                is_approved=False,\n            )\n        except IntegrityError:\n            return Response({'detail': _(u'User already linked to this organisation')},\n                            status=status.HTTP_409_CONFLICT)\n\n        data = EmploymentSerializer(employment).data\n        if data['country']:\n            data['country_full'] = employment.iati_country().name\n            data['country_name'] = str(employment.iati_country())\n        else:\n            data['country_full'] = ''\n        data['organisation_full'] = OrganisationSerializer(organisation).data\n        data['id'] = employment.pk\n\n        return Response(data)\n    else:\n        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)\n", "path": "akvo/rest/views/user.py"}, {"content": "# -*- coding: utf-8 -*-\n\n# Akvo RSR is covered by the GNU Affero General Public License.\n# See more details in the license.txt file located at the root folder of the Akvo RSR module.\n# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >.\n\nfrom akvo.codelists import models as codelist_models\nfrom akvo.codelists.store.codelists_v202 import COUNTRY\nfrom akvo.utils import codelist_choices, codelist_value\n\nfrom django.contrib.admin.models import LogEntry, CHANGE\nfrom django.contrib.auth import get_user_model\nfrom django.contrib.auth.models import Group\nfrom django.contrib.contenttypes.models import ContentType\nfrom django.core.exceptions import ObjectDoesNotExist\nfrom django.db import models\nfrom django.db.models.query import QuerySet as DjangoQuerySet\nfrom django.forms.models import model_to_dict\nfrom django.utils.encoding import force_unicode\nfrom django.utils.translation import ugettext_lazy as _\n\nfrom .models_utils import QuerySetManager\n\nfrom ..fields import ValidXMLCharField\n\n\nclass Employment(models.Model):\n    organisation = models.ForeignKey('Organisation', verbose_name=_(u'organisation'),\n                                     related_name='employees')\n    user = models.ForeignKey('User', verbose_name=_(u'user'), related_name='employers')\n    group = models.ForeignKey(Group, verbose_name=_(u'group'), null=True,\n                              related_name='employments', related_query_name='employment',\n                              on_delete=models.SET_NULL,\n                              help_text=_('The permissions group for this user\\'s employment.'))\n    is_approved = models.BooleanField(_('approved'), default=False,\n                                      help_text=_('Designates whether this employment is approved '\n                                                  'by an administrator.'))\n    country = ValidXMLCharField(\n        _(u'country'), blank=True, max_length=2, choices=codelist_choices(COUNTRY, show_code=False)\n    )\n    job_title = ValidXMLCharField(_(u'job title'), max_length=50, blank=True)\n\n    objects = QuerySetManager()\n\n    class QuerySet(DjangoQuerySet):\n        def organisations(self):\n            \"\"\"\n            Return an Organisation QuerySet containing the organisations of the Employment QuerySet\n            \"\"\"\n            from ..models import Organisation\n            return Organisation.objects.filter(employees__in=self).distinct()\n\n        def users(self):\n            \"\"\"\n            Return a User QuerySet containing the users of the Employment QuerySet\n            \"\"\"\n            return get_user_model().objects.filter(employers__in=self).distinct()\n\n        def approved(self):\n            \"\"\"\n            Return an Employment QuerySet containing the approved Employments\n            \"\"\"\n            return self.filter(is_approved=True)\n\n    class Meta:\n        app_label = 'rsr'\n        verbose_name = _(u'user employment')\n        verbose_name_plural = _(u'user employments')\n        unique_together = ('organisation', 'user', 'group')\n\n    def __unicode__(self):\n        return u\"{0} {1}: {2}\".format(self.user.first_name, self.user.last_name,\n                                      self.organisation.name)\n\n    def iati_country(self):\n        return codelist_value(codelist_models.Country, self, 'country')\n\n    def iati_country_unicode(self):\n        return str(self.iati_country())\n\n    def approve(self, approved_by):\n        \"\"\"\n        Approve an Employment. Will also be logged in the Employment admin history.\n\n        :param approved_by: User that approves the Employment\n        \"\"\"\n        if not self.is_approved:\n            self.is_approved = True\n            self.save()\n\n            # Log in Employment admin history\n            LogEntry.objects.log_action(\n                user_id=approved_by.pk,\n                content_type_id=ContentType.objects.get_for_model(self).pk,\n                object_id=self.pk,\n                object_repr=force_unicode(self),\n                action_flag=CHANGE,\n                change_message=u'Changed is_approved, outside of admin.'\n            )\n\n    def to_dict(self, org_list):\n        # Set groups in right order\n        all_groups = []\n        auth_group_names = ['Users', 'User Managers', 'Project Editors', 'Admins']\n        for auth_group_name in auth_group_names:\n            try:\n                all_groups.append(Group.objects.get(name=auth_group_name))\n            except ObjectDoesNotExist:\n                continue\n\n        user_group = model_to_dict(self.group, fields=['id', 'name']) if self.group else None\n        other_groups = [model_to_dict(group, fields=['id', 'name']) for group in all_groups]\n\n        return dict(\n            id=self.pk,\n            organisation_full=model_to_dict(self.organisation, fields=['id', 'name', 'long_name', ]),\n            user_full=model_to_dict(self.user, fields=['id', 'first_name', 'last_name', 'email', ]),\n            is_approved=self.is_approved,\n            job_title=self.job_title,\n            country_full=self.iati_country().name if self.country else '',\n            group=user_group,\n            other_groups=other_groups,\n            actions=True if self.organisation in org_list else False,\n        )\n", "path": "akvo/rsr/models/employment.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\n\"\"\"Akvo RSR is covered by the GNU Affero General Public License.\n\nSee more details in the license.txt file located at the root folder of the Akvo RSR module.\nFor additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >.\n\"\"\"\n\nfrom django.contrib.auth import get_user_model\nfrom django.db import IntegrityError\nfrom django.utils.translation import ugettext_lazy as _\n\nfrom rest_framework import status\nfrom rest_framework.authentication import SessionAuthentication\nfrom rest_framework.decorators import api_view\nfrom rest_framework.decorators import authentication_classes\nfrom rest_framework.exceptions import PermissionDenied\nfrom rest_framework.response import Response\n\nfrom akvo.rest.models import TastyTokenAuthentication\nfrom ...rsr.models import Employment\nfrom ...rsr.models import Organisation\nfrom ..viewsets import BaseRSRViewSet\nfrom ..serializers import EmploymentSerializer\nfrom ..serializers import OrganisationSerializer\nfrom ..serializers import UserSerializer, UserDetailsSerializer, UserPasswordSerializer\n\n\nclass UserViewSet(BaseRSRViewSet):\n\n    \"\"\"User resource.\"\"\"\n\n    queryset = get_user_model().objects.select_related(\n        'organisation',\n        'organisation__primary_location',\n        'organisation__primary_location__country',\n        'organisation__primary_location__location_target',\n        'organisation__primary_location__location_target__internal_org_ids',\n    ).prefetch_related(\n        'organisations',\n        'organisations__primary_location',\n        'organisations__primary_location__country',\n        'organisations__primary_location__location_target',)\n    serializer_class = UserSerializer\n\n\n@api_view(['POST'])\ndef change_password(request, pk=None):\n    # Get the user, or return an error if the user does not exist\n    try:\n        user = get_user_model().objects.get(pk=pk)\n    except get_user_model().DoesNotExist:\n        return Response({'user': _('User does not exist')}, status=status.HTTP_400_BAD_REQUEST)\n\n    # Users are only allowed to edit their own details\n    request_user = getattr(request, 'user', None)\n    if not user == request_user:\n        raise PermissionDenied()\n\n    # Process request\n    serializer = UserPasswordSerializer(data=request.data, instance=user)\n    if serializer.is_valid():\n        user = serializer.update(serializer.instance, serializer.validated_data)\n        user.save()\n        return Response({'status': 'password set'})\n    else:\n        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)\n\n\n@api_view(['POST'])\ndef update_details(request, pk=None):\n    # Get the user, or return an error if the user does not exist\n    try:\n        user = get_user_model().objects.get(pk=pk)\n    except get_user_model().DoesNotExist:\n        return Response({'user': _('User does not exist')}, status=status.HTTP_400_BAD_REQUEST)\n\n    # Users are only allowed to edit their own details\n    request_user = getattr(request, 'user', None)\n    if not user == request_user:\n        raise PermissionDenied()\n\n    # Process request\n    serializer = UserDetailsSerializer(data=request.data)\n    if serializer.is_valid():\n        serializer.update(user, serializer.initial_data)\n        return Response(request.data)\n    else:\n        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)\n\n\n@api_view(['POST'])\n@authentication_classes([SessionAuthentication, TastyTokenAuthentication])\ndef request_organisation(request, pk=None):\n\n    # Add missing keys to request.data to simplify code and getting working\n    # with DRF-3 Serializer\n    for key in ('group', 'country', 'job_title'):\n        if key not in request.data:\n            request.data[key] = ''\n\n    # Get the user, or return an error if the user does not exist\n    try:\n        user_by_pk = get_user_model().objects.get(pk=pk)\n    except get_user_model().DoesNotExist:\n        return Response({'user': _('User does not exist')}, status=status.HTTP_400_BAD_REQUEST)\n\n    # request.user is the user identified by the auth token\n    user = request.user\n    # Users themselves are only allowed to request to join an organisation\n    if not user_by_pk == user:\n        raise PermissionDenied()\n    request.data['user'] = pk\n\n    # Process request\n    serializer = EmploymentSerializer(data=request.data)\n    if serializer.is_valid():\n        try:\n            organisation = Organisation.objects.get(pk=serializer.data['organisation'])\n            employment = Employment.objects.create(\n                user=user,\n                organisation=organisation,\n                country=serializer.data['country'],\n                job_title=serializer.data['job_title'],\n                is_approved=False,\n            )\n        except IntegrityError:\n            return Response({'detail': _(u'User already linked to this organisation')},\n                            status=status.HTTP_409_CONFLICT)\n\n        data = EmploymentSerializer(employment).data\n        if data['country']:\n            data['country_full'] = employment.iati_country().name\n            data['country_name'] = unicode(employment.iati_country())\n        else:\n            data['country_full'] = ''\n        data['organisation_full'] = OrganisationSerializer(organisation).data\n        data['id'] = employment.pk\n\n        return Response(data)\n    else:\n        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)\n", "path": "akvo/rest/views/user.py"}, {"content": "# -*- coding: utf-8 -*-\n\n# Akvo RSR is covered by the GNU Affero General Public License.\n# See more details in the license.txt file located at the root folder of the Akvo RSR module.\n# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >.\n\nfrom akvo.codelists import models as codelist_models\nfrom akvo.codelists.store.codelists_v202 import COUNTRY\nfrom akvo.utils import codelist_choices, codelist_value\n\nfrom django.contrib.admin.models import LogEntry, CHANGE\nfrom django.contrib.auth import get_user_model\nfrom django.contrib.auth.models import Group\nfrom django.contrib.contenttypes.models import ContentType\nfrom django.core.exceptions import ObjectDoesNotExist\nfrom django.db import models\nfrom django.db.models.query import QuerySet as DjangoQuerySet\nfrom django.forms.models import model_to_dict\nfrom django.utils.encoding import force_unicode\nfrom django.utils.translation import ugettext_lazy as _\n\nfrom .models_utils import QuerySetManager\n\nfrom ..fields import ValidXMLCharField\n\n\nclass Employment(models.Model):\n    organisation = models.ForeignKey('Organisation', verbose_name=_(u'organisation'),\n                                     related_name='employees')\n    user = models.ForeignKey('User', verbose_name=_(u'user'), related_name='employers')\n    group = models.ForeignKey(Group, verbose_name=_(u'group'), null=True,\n                              related_name='employments', related_query_name='employment',\n                              on_delete=models.SET_NULL,\n                              help_text=_('The permissions group for this user\\'s employment.'))\n    is_approved = models.BooleanField(_('approved'), default=False,\n                                      help_text=_('Designates whether this employment is approved '\n                                                  'by an administrator.'))\n    country = ValidXMLCharField(\n        _(u'country'), blank=True, max_length=2, choices=codelist_choices(COUNTRY, show_code=False)\n    )\n    job_title = ValidXMLCharField(_(u'job title'), max_length=50, blank=True)\n\n    objects = QuerySetManager()\n\n    class QuerySet(DjangoQuerySet):\n        def organisations(self):\n            \"\"\"\n            Return an Organisation QuerySet containing the organisations of the Employment QuerySet\n            \"\"\"\n            from ..models import Organisation\n            return Organisation.objects.filter(employees__in=self).distinct()\n\n        def users(self):\n            \"\"\"\n            Return a User QuerySet containing the users of the Employment QuerySet\n            \"\"\"\n            return get_user_model().objects.filter(employers__in=self).distinct()\n\n        def approved(self):\n            \"\"\"\n            Return an Employment QuerySet containing the approved Employments\n            \"\"\"\n            return self.filter(is_approved=True)\n\n    class Meta:\n        app_label = 'rsr'\n        verbose_name = _(u'user employment')\n        verbose_name_plural = _(u'user employments')\n        unique_together = ('organisation', 'user', 'group')\n\n    def __unicode__(self):\n        return u\"{0} {1}: {2}\".format(self.user.first_name, self.user.last_name,\n                                      self.organisation.name)\n\n    def iati_country(self):\n        return codelist_value(codelist_models.Country, self, 'country')\n\n    def iati_country_unicode(self):\n        return unicode(self.iati_country())\n\n    def approve(self, approved_by):\n        \"\"\"\n        Approve an Employment. Will also be logged in the Employment admin history.\n\n        :param approved_by: User that approves the Employment\n        \"\"\"\n        if not self.is_approved:\n            self.is_approved = True\n            self.save()\n\n            # Log in Employment admin history\n            LogEntry.objects.log_action(\n                user_id=approved_by.pk,\n                content_type_id=ContentType.objects.get_for_model(self).pk,\n                object_id=self.pk,\n                object_repr=force_unicode(self),\n                action_flag=CHANGE,\n                change_message=u'Changed is_approved, outside of admin.'\n            )\n\n    def to_dict(self, org_list):\n        # Set groups in right order\n        all_groups = []\n        auth_group_names = ['Users', 'User Managers', 'Project Editors', 'Admins']\n        for auth_group_name in auth_group_names:\n            try:\n                all_groups.append(Group.objects.get(name=auth_group_name))\n            except ObjectDoesNotExist:\n                continue\n\n        user_group = model_to_dict(self.group, fields=['id', 'name']) if self.group else None\n        other_groups = [model_to_dict(group, fields=['id', 'name']) for group in all_groups]\n\n        return dict(\n            id=self.pk,\n            organisation_full=model_to_dict(self.organisation, fields=['id', 'name', 'long_name', ]),\n            user_full=model_to_dict(self.user, fields=['id', 'first_name', 'last_name', 'email', ]),\n            is_approved=self.is_approved,\n            job_title=self.job_title,\n            country_full=self.iati_country().name if self.country else '',\n            group=user_group,\n            other_groups=other_groups,\n            actions=True if self.organisation in org_list else False,\n        )\n", "path": "akvo/rsr/models/employment.py"}]}