We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Reuse the __unicode__ on ProjectLocation other types of locations
Also, display the country for a location, since it is inferred and not showing it in the UI makes it bad UX. 

--- 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/rsr/models/location.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 
8 from django.db import models
9 from django.utils.translation import ugettext_lazy as _
10 
11 from ..fields import LatitudeField, LongitudeField, ValidXMLCharField
12 from akvo.codelists.models import (Country, GeographicExactness, GeographicLocationClass,
13                                    GeographicLocationReach, GeographicVocabulary, LocationType)
14 from akvo.codelists.store.codelists_v202 import (
15     COUNTRY, GEOGRAPHIC_EXACTNESS, GEOGRAPHIC_LOCATION_CLASS, GEOGRAPHIC_LOCATION_REACH,
16     GEOGRAPHIC_VOCABULARY, LOCATION_TYPE
17 )
18 from akvo.utils import codelist_choices, codelist_value, get_country
19 
20 
21 class BaseLocation(models.Model):
22     latitude = LatitudeField(
23         _(u'latitude'), null=True, blank=True, db_index=True, default=None,
24         help_text=_(u'Use a period to denote decimals.')
25     )
26     longitude = LongitudeField(
27         _(u'longitude'), null=True, blank=True, db_index=True, default=None,
28         help_text=_(u'Use a period to denote decimals.')
29     )
30     city = ValidXMLCharField(_(u'city'), blank=True, max_length=255)
31     state = ValidXMLCharField(_(u'state'), blank=True, max_length=255)
32     address_1 = ValidXMLCharField(_(u'address 1'), max_length=255, blank=True)
33     address_2 = ValidXMLCharField(_(u'address 2'), max_length=255, blank=True)
34     postcode = ValidXMLCharField(_(u'postal code'), max_length=10, blank=True)
35     country = models.ForeignKey('Country', null=True, blank=True, verbose_name=_(u'country'))
36 
37     def delete(self, *args, **kwargs):
38         super(BaseLocation, self).delete(*args, **kwargs)
39 
40         # If location_target has more locations, set the first as primary location
41         location_target = self.location_target
42         other_locations = location_target.locations.all()
43 
44         if other_locations.count() > 0:
45             location_target.primary_location = other_locations.first()
46         else:
47             location_target.primary_location = None
48 
49         location_target.save()
50 
51     def save(self, *args, **kwargs):
52         get_country = False
53         if not self.pk:
54             get_country = True
55 
56         else:
57             original = self._meta.model.objects.get(id=self.pk)
58             if original.latitude != self.latitude or original.longitude != self.longitude:
59                 get_country = True
60 
61         # Set a country based on the latitude and longitude if possible
62         if get_country and self.latitude is not None and self.longitude is not None:
63             self.country = self.get_country_from_lat_lon()
64             if 'update_fields' in kwargs and 'country' not in kwargs['update_fields']:
65                 kwargs['update_fields'].append('country')
66 
67         super(BaseLocation, self).save(*args, **kwargs)
68 
69         # Set location as primary location if it is the first location
70         location_target = self.location_target
71         if location_target.primary_location is None or location_target.primary_location.pk > self.pk:
72             location_target.primary_location = self
73             location_target.save()
74 
75     def get_country_from_lat_lon(self):
76         """Get the country based on the location's latitude and longitude."""
77 
78         if self.latitude is None or self.longitude is None:
79             return None
80 
81         try:
82             country, iso_code = get_country(float(self.latitude), float(self.longitude))
83         except ValueError:
84             iso_code = None
85 
86         if iso_code is not None:
87             # FIXME: We have one too many country models!
88             Country = models.get_model('rsr', 'Country')
89             return Country.objects.filter(iso_code=iso_code).first()
90 
91     class Meta:
92         app_label = 'rsr'
93         abstract = True
94         ordering = ['id', ]
95 
96 
97 class OrganisationLocation(BaseLocation):
98     location_target = models.ForeignKey('Organisation', related_name='locations')
99     iati_country = ValidXMLCharField(
100         _(u'country'), blank=True, max_length=2, choices=codelist_choices(COUNTRY, show_code=False),
101         help_text=_(u'The country in which the organisation is located.')
102     )
103 
104     def iati_country_value(self):
105         return codelist_value(Country, self, 'iati_country')
106 
107     def iati_country_value_unicode(self):
108         return unicode(self.iati_country_value())
109 
110 
111 class ProjectLocation(BaseLocation):
112     location_target = models.ForeignKey('Project', related_name='locations')
113 
114     # Additional IATI fields
115     reference = ValidXMLCharField(
116         _(u'reference'), blank=True, max_length=50,
117         help_text=_(u'An internal reference that describes the location in the reporting '
118                     u'organisation\'s own system. For reference see: '
119                     u'<a href="http://iatistandard.org/202/activity-standard/iati-activities/'
120                     u'iati-activity/location/#attributes" target="_blank">'
121                     u'http://iatistandard.org/202/activity-standard/iati-activities/iati-activity/'
122                     u'location/#attributes</a>.')
123     )
124     location_code = ValidXMLCharField(
125         _(u'code'), blank=True, max_length=25,
126         help_text=_(u'Enter a code to identify the region. Codes are based on DAC region codes. '
127                     u'Where an activity is considered global, the code 998 can be used. For '
128                     u'reference: <a href="http://www.oecd.org/dac/stats/dacandcrscodelists.htm" '
129                     u'target="_blank">http://www.oecd.org/dac/stats/dacandcrscodelists.htm</a>.')
130     )
131     vocabulary = ValidXMLCharField(_(u'vocabulary'), blank=True, max_length=2,
132                                    choices=codelist_choices(GEOGRAPHIC_VOCABULARY))
133     name = ValidXMLCharField(
134         _(u'name'), blank=True, max_length=100,
135         help_text=_(u'The human-readable name for the location.')
136     )
137     description = ValidXMLCharField(
138         _(u'location description'), blank=True, max_length=2000,
139         help_text=_(u'This provides free text space for providing an additional description, if '
140                     u'needed, of the actual target of the activity. A description that qualifies '
141                     u'the location, not the activity.')
142     )
143     activity_description = ValidXMLCharField(
144         _(u'activity description'), blank=True, max_length=2000,
145         help_text=_(u'A description that qualifies the activity taking place at the location. '
146                     u'This should not duplicate information provided in the main activity '
147                     u'description, and should typically be used to distinguish between activities '
148                     u'at multiple locations within a single iati-activity record.')
149     )
150     exactness = ValidXMLCharField(
151         _(u'location precision'), blank=True, max_length=1,
152         choices=codelist_choices(GEOGRAPHIC_EXACTNESS),
153         help_text=_(u'Defines whether the location represents the most distinct point reasonably '
154                     u'possible for this type of activity or is an approximation due to lack of '
155                     u'more detailed information.')
156     )
157     location_reach = ValidXMLCharField(
158         _(u'reach'), blank=True, max_length=1, choices=codelist_choices(GEOGRAPHIC_LOCATION_REACH),
159         help_text=_(u'Does this location describe where the activity takes place or where the '
160                     u'intended beneficiaries reside?')
161     )
162     location_class = ValidXMLCharField(
163         _(u'class'), blank=True, max_length=1, choices=codelist_choices(GEOGRAPHIC_LOCATION_CLASS),
164         help_text=_(u'Does the location refer to a physical structure such as a building, a '
165                     u'populated place (e.g. city or village), an administrative division, or '
166                     u'another topological feature (e.g. river, nature reserve)? For reference: '
167                     u'<a href="http://iatistandard.org/202/codelists/GeographicLocationClass/" '
168                     u'target="_blank">http://iatistandard.org/202/codelists/'
169                     u'GeographicLocationClass/</a>.')
170     )
171     feature_designation = ValidXMLCharField(
172         _(u'feature designation'), blank=True, max_length=5,
173         choices=codelist_choices(LOCATION_TYPE),
174         help_text=_(u'A more refined coded classification of the type of feature referred to by '
175                     u'this location. For reference: <a href="http://iatistandard.org/202/codelists/'
176                     u'LocationType/" target="_blank">http://iatistandard.org/202/codelists/'
177                     u'LocationType/</a>.')
178     )
179 
180     def __unicode__(self):
181         return u'{0}, {1}{2}'.format(
182             u'{0}: {1}'.format(
183                 _(u'Latitude'),
184                 unicode(self.latitude) if self.latitude else _(u'No latitude specified')),
185             u'{0}: {1}'.format(
186                 _(u'Longitude'),
187                 unicode(self.longitude) if self.longitude else _(u'No longitude specified')),
188             u' ({0})'.format(self.name) if self.name else u''
189         )
190 
191     def iati_country(self):
192         return codelist_value(Country, self, 'country')
193 
194     def iati_country_unicode(self):
195         return unicode(self.iati_country())
196 
197     def iati_vocabulary(self):
198         return codelist_value(GeographicVocabulary, self, 'vocabulary')
199 
200     def iati_vocabulary_unicode(self):
201         return unicode(self.iati_vocabulary())
202 
203     def iati_exactness(self):
204         return codelist_value(GeographicExactness, self, 'exactness')
205 
206     def iati_exactness_unicode(self):
207         return unicode(self.iati_exactness())
208 
209     def iati_reach(self):
210         return codelist_value(GeographicLocationReach, self, 'location_reach')
211 
212     def iati_reach_unicode(self):
213         return unicode(self.iati_reach())
214 
215     def iati_class(self):
216         return codelist_value(GeographicLocationClass, self, 'location_class')
217 
218     def iati_class_unicode(self):
219         return unicode(self.iati_class())
220 
221     def iati_designation(self):
222         return codelist_value(LocationType, self, 'feature_designation')
223 
224     def iati_designation_unicode(self):
225         return unicode(self.iati_designation())
226 
227 
228 # Over-riding fields doesn't work in Django < 1.10, and hence this hack.
229 ProjectLocation._meta.get_field('country').help_text = _(
230     u'The country or countries that benefit(s) from the activity.'
231 )
232 
233 
234 class AdministrativeLocation(models.Model):
235     location = models.ForeignKey(
236         'ProjectLocation', verbose_name=_(u'location'), related_name='administratives'
237     )
238     code = ValidXMLCharField(
239         _(u'administrative code'), blank=True, max_length=25,
240         help_text=_(u'Coded identification of national and sub-national divisions according to '
241                     u'recognised administrative boundary repositories. Multiple levels may be '
242                     u'reported.')
243     )
244     vocabulary = ValidXMLCharField(
245         _(u'administrative vocabulary'), blank=True, max_length=2,
246         choices=codelist_choices(GEOGRAPHIC_VOCABULARY),
247         help_text=_(u'For reference: <a href="http://iatistandard.org/202/codelists/'
248                     u'GeographicVocabulary/" target="_blank">http://iatistandard.org/202/codelists/'
249                     u'GeographicVocabulary/</a>.')
250     )
251 
252     level = models.PositiveSmallIntegerField(_(u'administrative level'), blank=True, null=True)
253 
254     def __unicode__(self):
255         return unicode(self.code) if self.code else u'%s' % _(u'No code specified')
256 
257     def iati_vocabulary(self):
258         return codelist_value(GeographicVocabulary, self, 'vocabulary')
259 
260     def iati_vocabulary_unicode(self):
261         return unicode(self.iati_vocabulary())
262 
263     class Meta:
264         app_label = 'rsr'
265         verbose_name = _(u'location administrative')
266         verbose_name_plural = _(u'location administratives')
267 
268 
269 class ProjectUpdateLocation(BaseLocation):
270     location_target = models.ForeignKey('ProjectUpdate', related_name='locations')
271
```
--- 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/rsr/models/location.py b/akvo/rsr/models/location.py
--- a/akvo/rsr/models/location.py
+++ b/akvo/rsr/models/location.py
@@ -34,6 +34,20 @@
     postcode = ValidXMLCharField(_(u'postal code'), max_length=10, blank=True)
     country = models.ForeignKey('Country', null=True, blank=True, verbose_name=_(u'country'))
 
+    def __unicode__(self):
+        return u'{0}, {1}, {2}{3}'.format(
+            u'{0}: {1}'.format(
+                _(u'Latitude'),
+                unicode(self.latitude) if self.latitude else _(u'No latitude specified')),
+            u'{0}: {1}'.format(
+                _(u'Longitude'),
+                unicode(self.longitude) if self.longitude else _(u'No longitude specified')),
+            u'{0}: {1}'.format(
+                _(u'Country'),
+                unicode(self.country.name) if self.country else _(u'No country specified')),
+            u' ({0})'.format(self.name) if getattr(self, 'name', None) else u''
+        )
+
     def delete(self, *args, **kwargs):
         super(BaseLocation, self).delete(*args, **kwargs)
 
@@ -177,17 +191,6 @@
                     u'LocationType/</a>.')
     )
 
-    def __unicode__(self):
-        return u'{0}, {1}{2}'.format(
-            u'{0}: {1}'.format(
-                _(u'Latitude'),
-                unicode(self.latitude) if self.latitude else _(u'No latitude specified')),
-            u'{0}: {1}'.format(
-                _(u'Longitude'),
-                unicode(self.longitude) if self.longitude else _(u'No longitude specified')),
-            u' ({0})'.format(self.name) if self.name else u''
-        )
-
     def iati_country(self):
         return codelist_value(Country, self, 'country')

{"golden_diff": "diff --git a/akvo/rsr/models/location.py b/akvo/rsr/models/location.py\n--- a/akvo/rsr/models/location.py\n+++ b/akvo/rsr/models/location.py\n@@ -34,6 +34,20 @@\n     postcode = ValidXMLCharField(_(u'postal code'), max_length=10, blank=True)\n     country = models.ForeignKey('Country', null=True, blank=True, verbose_name=_(u'country'))\n \n+    def __unicode__(self):\n+        return u'{0}, {1}, {2}{3}'.format(\n+            u'{0}: {1}'.format(\n+                _(u'Latitude'),\n+                unicode(self.latitude) if self.latitude else _(u'No latitude specified')),\n+            u'{0}: {1}'.format(\n+                _(u'Longitude'),\n+                unicode(self.longitude) if self.longitude else _(u'No longitude specified')),\n+            u'{0}: {1}'.format(\n+                _(u'Country'),\n+                unicode(self.country.name) if self.country else _(u'No country specified')),\n+            u' ({0})'.format(self.name) if getattr(self, 'name', None) else u''\n+        )\n+\n     def delete(self, *args, **kwargs):\n         super(BaseLocation, self).delete(*args, **kwargs)\n \n@@ -177,17 +191,6 @@\n                     u'LocationType/</a>.')\n     )\n \n-    def __unicode__(self):\n-        return u'{0}, {1}{2}'.format(\n-            u'{0}: {1}'.format(\n-                _(u'Latitude'),\n-                unicode(self.latitude) if self.latitude else _(u'No latitude specified')),\n-            u'{0}: {1}'.format(\n-                _(u'Longitude'),\n-                unicode(self.longitude) if self.longitude else _(u'No longitude specified')),\n-            u' ({0})'.format(self.name) if self.name else u''\n-        )\n-\n     def iati_country(self):\n         return codelist_value(Country, self, 'country')\n", "issue": "Reuse the __unicode__ on ProjectLocation other types of locations\nAlso, display the country for a location, since it is inferred and not showing it in the UI makes it bad UX. \n", "before_files": [{"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\n\nfrom django.db import models\nfrom django.utils.translation import ugettext_lazy as _\n\nfrom ..fields import LatitudeField, LongitudeField, ValidXMLCharField\nfrom akvo.codelists.models import (Country, GeographicExactness, GeographicLocationClass,\n                                   GeographicLocationReach, GeographicVocabulary, LocationType)\nfrom akvo.codelists.store.codelists_v202 import (\n    COUNTRY, GEOGRAPHIC_EXACTNESS, GEOGRAPHIC_LOCATION_CLASS, GEOGRAPHIC_LOCATION_REACH,\n    GEOGRAPHIC_VOCABULARY, LOCATION_TYPE\n)\nfrom akvo.utils import codelist_choices, codelist_value, get_country\n\n\nclass BaseLocation(models.Model):\n    latitude = LatitudeField(\n        _(u'latitude'), null=True, blank=True, db_index=True, default=None,\n        help_text=_(u'Use a period to denote decimals.')\n    )\n    longitude = LongitudeField(\n        _(u'longitude'), null=True, blank=True, db_index=True, default=None,\n        help_text=_(u'Use a period to denote decimals.')\n    )\n    city = ValidXMLCharField(_(u'city'), blank=True, max_length=255)\n    state = ValidXMLCharField(_(u'state'), blank=True, max_length=255)\n    address_1 = ValidXMLCharField(_(u'address 1'), max_length=255, blank=True)\n    address_2 = ValidXMLCharField(_(u'address 2'), max_length=255, blank=True)\n    postcode = ValidXMLCharField(_(u'postal code'), max_length=10, blank=True)\n    country = models.ForeignKey('Country', null=True, blank=True, verbose_name=_(u'country'))\n\n    def delete(self, *args, **kwargs):\n        super(BaseLocation, self).delete(*args, **kwargs)\n\n        # If location_target has more locations, set the first as primary location\n        location_target = self.location_target\n        other_locations = location_target.locations.all()\n\n        if other_locations.count() > 0:\n            location_target.primary_location = other_locations.first()\n        else:\n            location_target.primary_location = None\n\n        location_target.save()\n\n    def save(self, *args, **kwargs):\n        get_country = False\n        if not self.pk:\n            get_country = True\n\n        else:\n            original = self._meta.model.objects.get(id=self.pk)\n            if original.latitude != self.latitude or original.longitude != self.longitude:\n                get_country = True\n\n        # Set a country based on the latitude and longitude if possible\n        if get_country and self.latitude is not None and self.longitude is not None:\n            self.country = self.get_country_from_lat_lon()\n            if 'update_fields' in kwargs and 'country' not in kwargs['update_fields']:\n                kwargs['update_fields'].append('country')\n\n        super(BaseLocation, self).save(*args, **kwargs)\n\n        # Set location as primary location if it is the first location\n        location_target = self.location_target\n        if location_target.primary_location is None or location_target.primary_location.pk > self.pk:\n            location_target.primary_location = self\n            location_target.save()\n\n    def get_country_from_lat_lon(self):\n        \"\"\"Get the country based on the location's latitude and longitude.\"\"\"\n\n        if self.latitude is None or self.longitude is None:\n            return None\n\n        try:\n            country, iso_code = get_country(float(self.latitude), float(self.longitude))\n        except ValueError:\n            iso_code = None\n\n        if iso_code is not None:\n            # FIXME: We have one too many country models!\n            Country = models.get_model('rsr', 'Country')\n            return Country.objects.filter(iso_code=iso_code).first()\n\n    class Meta:\n        app_label = 'rsr'\n        abstract = True\n        ordering = ['id', ]\n\n\nclass OrganisationLocation(BaseLocation):\n    location_target = models.ForeignKey('Organisation', related_name='locations')\n    iati_country = ValidXMLCharField(\n        _(u'country'), blank=True, max_length=2, choices=codelist_choices(COUNTRY, show_code=False),\n        help_text=_(u'The country in which the organisation is located.')\n    )\n\n    def iati_country_value(self):\n        return codelist_value(Country, self, 'iati_country')\n\n    def iati_country_value_unicode(self):\n        return unicode(self.iati_country_value())\n\n\nclass ProjectLocation(BaseLocation):\n    location_target = models.ForeignKey('Project', related_name='locations')\n\n    # Additional IATI fields\n    reference = ValidXMLCharField(\n        _(u'reference'), blank=True, max_length=50,\n        help_text=_(u'An internal reference that describes the location in the reporting '\n                    u'organisation\\'s own system. For reference see: '\n                    u'<a href=\"http://iatistandard.org/202/activity-standard/iati-activities/'\n                    u'iati-activity/location/#attributes\" target=\"_blank\">'\n                    u'http://iatistandard.org/202/activity-standard/iati-activities/iati-activity/'\n                    u'location/#attributes</a>.')\n    )\n    location_code = ValidXMLCharField(\n        _(u'code'), blank=True, max_length=25,\n        help_text=_(u'Enter a code to identify the region. Codes are based on DAC region codes. '\n                    u'Where an activity is considered global, the code 998 can be used. For '\n                    u'reference: <a href=\"http://www.oecd.org/dac/stats/dacandcrscodelists.htm\" '\n                    u'target=\"_blank\">http://www.oecd.org/dac/stats/dacandcrscodelists.htm</a>.')\n    )\n    vocabulary = ValidXMLCharField(_(u'vocabulary'), blank=True, max_length=2,\n                                   choices=codelist_choices(GEOGRAPHIC_VOCABULARY))\n    name = ValidXMLCharField(\n        _(u'name'), blank=True, max_length=100,\n        help_text=_(u'The human-readable name for the location.')\n    )\n    description = ValidXMLCharField(\n        _(u'location description'), blank=True, max_length=2000,\n        help_text=_(u'This provides free text space for providing an additional description, if '\n                    u'needed, of the actual target of the activity. A description that qualifies '\n                    u'the location, not the activity.')\n    )\n    activity_description = ValidXMLCharField(\n        _(u'activity description'), blank=True, max_length=2000,\n        help_text=_(u'A description that qualifies the activity taking place at the location. '\n                    u'This should not duplicate information provided in the main activity '\n                    u'description, and should typically be used to distinguish between activities '\n                    u'at multiple locations within a single iati-activity record.')\n    )\n    exactness = ValidXMLCharField(\n        _(u'location precision'), blank=True, max_length=1,\n        choices=codelist_choices(GEOGRAPHIC_EXACTNESS),\n        help_text=_(u'Defines whether the location represents the most distinct point reasonably '\n                    u'possible for this type of activity or is an approximation due to lack of '\n                    u'more detailed information.')\n    )\n    location_reach = ValidXMLCharField(\n        _(u'reach'), blank=True, max_length=1, choices=codelist_choices(GEOGRAPHIC_LOCATION_REACH),\n        help_text=_(u'Does this location describe where the activity takes place or where the '\n                    u'intended beneficiaries reside?')\n    )\n    location_class = ValidXMLCharField(\n        _(u'class'), blank=True, max_length=1, choices=codelist_choices(GEOGRAPHIC_LOCATION_CLASS),\n        help_text=_(u'Does the location refer to a physical structure such as a building, a '\n                    u'populated place (e.g. city or village), an administrative division, or '\n                    u'another topological feature (e.g. river, nature reserve)? For reference: '\n                    u'<a href=\"http://iatistandard.org/202/codelists/GeographicLocationClass/\" '\n                    u'target=\"_blank\">http://iatistandard.org/202/codelists/'\n                    u'GeographicLocationClass/</a>.')\n    )\n    feature_designation = ValidXMLCharField(\n        _(u'feature designation'), blank=True, max_length=5,\n        choices=codelist_choices(LOCATION_TYPE),\n        help_text=_(u'A more refined coded classification of the type of feature referred to by '\n                    u'this location. For reference: <a href=\"http://iatistandard.org/202/codelists/'\n                    u'LocationType/\" target=\"_blank\">http://iatistandard.org/202/codelists/'\n                    u'LocationType/</a>.')\n    )\n\n    def __unicode__(self):\n        return u'{0}, {1}{2}'.format(\n            u'{0}: {1}'.format(\n                _(u'Latitude'),\n                unicode(self.latitude) if self.latitude else _(u'No latitude specified')),\n            u'{0}: {1}'.format(\n                _(u'Longitude'),\n                unicode(self.longitude) if self.longitude else _(u'No longitude specified')),\n            u' ({0})'.format(self.name) if self.name else u''\n        )\n\n    def iati_country(self):\n        return codelist_value(Country, self, 'country')\n\n    def iati_country_unicode(self):\n        return unicode(self.iati_country())\n\n    def iati_vocabulary(self):\n        return codelist_value(GeographicVocabulary, self, 'vocabulary')\n\n    def iati_vocabulary_unicode(self):\n        return unicode(self.iati_vocabulary())\n\n    def iati_exactness(self):\n        return codelist_value(GeographicExactness, self, 'exactness')\n\n    def iati_exactness_unicode(self):\n        return unicode(self.iati_exactness())\n\n    def iati_reach(self):\n        return codelist_value(GeographicLocationReach, self, 'location_reach')\n\n    def iati_reach_unicode(self):\n        return unicode(self.iati_reach())\n\n    def iati_class(self):\n        return codelist_value(GeographicLocationClass, self, 'location_class')\n\n    def iati_class_unicode(self):\n        return unicode(self.iati_class())\n\n    def iati_designation(self):\n        return codelist_value(LocationType, self, 'feature_designation')\n\n    def iati_designation_unicode(self):\n        return unicode(self.iati_designation())\n\n\n# Over-riding fields doesn't work in Django < 1.10, and hence this hack.\nProjectLocation._meta.get_field('country').help_text = _(\n    u'The country or countries that benefit(s) from the activity.'\n)\n\n\nclass AdministrativeLocation(models.Model):\n    location = models.ForeignKey(\n        'ProjectLocation', verbose_name=_(u'location'), related_name='administratives'\n    )\n    code = ValidXMLCharField(\n        _(u'administrative code'), blank=True, max_length=25,\n        help_text=_(u'Coded identification of national and sub-national divisions according to '\n                    u'recognised administrative boundary repositories. Multiple levels may be '\n                    u'reported.')\n    )\n    vocabulary = ValidXMLCharField(\n        _(u'administrative vocabulary'), blank=True, max_length=2,\n        choices=codelist_choices(GEOGRAPHIC_VOCABULARY),\n        help_text=_(u'For reference: <a href=\"http://iatistandard.org/202/codelists/'\n                    u'GeographicVocabulary/\" target=\"_blank\">http://iatistandard.org/202/codelists/'\n                    u'GeographicVocabulary/</a>.')\n    )\n\n    level = models.PositiveSmallIntegerField(_(u'administrative level'), blank=True, null=True)\n\n    def __unicode__(self):\n        return unicode(self.code) if self.code else u'%s' % _(u'No code specified')\n\n    def iati_vocabulary(self):\n        return codelist_value(GeographicVocabulary, self, 'vocabulary')\n\n    def iati_vocabulary_unicode(self):\n        return unicode(self.iati_vocabulary())\n\n    class Meta:\n        app_label = 'rsr'\n        verbose_name = _(u'location administrative')\n        verbose_name_plural = _(u'location administratives')\n\n\nclass ProjectUpdateLocation(BaseLocation):\n    location_target = models.ForeignKey('ProjectUpdate', related_name='locations')\n", "path": "akvo/rsr/models/location.py"}], "after_files": [{"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\n\nfrom django.db import models\nfrom django.utils.translation import ugettext_lazy as _\n\nfrom ..fields import LatitudeField, LongitudeField, ValidXMLCharField\nfrom akvo.codelists.models import (Country, GeographicExactness, GeographicLocationClass,\n                                   GeographicLocationReach, GeographicVocabulary, LocationType)\nfrom akvo.codelists.store.codelists_v202 import (\n    COUNTRY, GEOGRAPHIC_EXACTNESS, GEOGRAPHIC_LOCATION_CLASS, GEOGRAPHIC_LOCATION_REACH,\n    GEOGRAPHIC_VOCABULARY, LOCATION_TYPE\n)\nfrom akvo.utils import codelist_choices, codelist_value, get_country\n\n\nclass BaseLocation(models.Model):\n    latitude = LatitudeField(\n        _(u'latitude'), null=True, blank=True, db_index=True, default=None,\n        help_text=_(u'Use a period to denote decimals.')\n    )\n    longitude = LongitudeField(\n        _(u'longitude'), null=True, blank=True, db_index=True, default=None,\n        help_text=_(u'Use a period to denote decimals.')\n    )\n    city = ValidXMLCharField(_(u'city'), blank=True, max_length=255)\n    state = ValidXMLCharField(_(u'state'), blank=True, max_length=255)\n    address_1 = ValidXMLCharField(_(u'address 1'), max_length=255, blank=True)\n    address_2 = ValidXMLCharField(_(u'address 2'), max_length=255, blank=True)\n    postcode = ValidXMLCharField(_(u'postal code'), max_length=10, blank=True)\n    country = models.ForeignKey('Country', null=True, blank=True, verbose_name=_(u'country'))\n\n    def __unicode__(self):\n        return u'{0}, {1}, {2}{3}'.format(\n            u'{0}: {1}'.format(\n                _(u'Latitude'),\n                unicode(self.latitude) if self.latitude else _(u'No latitude specified')),\n            u'{0}: {1}'.format(\n                _(u'Longitude'),\n                unicode(self.longitude) if self.longitude else _(u'No longitude specified')),\n            u'{0}: {1}'.format(\n                _(u'Country'),\n                unicode(self.country.name) if self.country else _(u'No country specified')),\n            u' ({0})'.format(self.name) if getattr(self, 'name', None) else u''\n        )\n\n    def delete(self, *args, **kwargs):\n        super(BaseLocation, self).delete(*args, **kwargs)\n\n        # If location_target has more locations, set the first as primary location\n        location_target = self.location_target\n        other_locations = location_target.locations.all()\n\n        if other_locations.count() > 0:\n            location_target.primary_location = other_locations.first()\n        else:\n            location_target.primary_location = None\n\n        location_target.save()\n\n    def save(self, *args, **kwargs):\n        get_country = False\n        if not self.pk:\n            get_country = True\n\n        else:\n            original = self._meta.model.objects.get(id=self.pk)\n            if original.latitude != self.latitude or original.longitude != self.longitude:\n                get_country = True\n\n        # Set a country based on the latitude and longitude if possible\n        if get_country and self.latitude is not None and self.longitude is not None:\n            self.country = self.get_country_from_lat_lon()\n            if 'update_fields' in kwargs and 'country' not in kwargs['update_fields']:\n                kwargs['update_fields'].append('country')\n\n        super(BaseLocation, self).save(*args, **kwargs)\n\n        # Set location as primary location if it is the first location\n        location_target = self.location_target\n        if location_target.primary_location is None or location_target.primary_location.pk > self.pk:\n            location_target.primary_location = self\n            location_target.save()\n\n    def get_country_from_lat_lon(self):\n        \"\"\"Get the country based on the location's latitude and longitude.\"\"\"\n\n        if self.latitude is None or self.longitude is None:\n            return None\n\n        try:\n            country, iso_code = get_country(float(self.latitude), float(self.longitude))\n        except ValueError:\n            iso_code = None\n\n        if iso_code is not None:\n            # FIXME: We have one too many country models!\n            Country = models.get_model('rsr', 'Country')\n            return Country.objects.filter(iso_code=iso_code).first()\n\n    class Meta:\n        app_label = 'rsr'\n        abstract = True\n        ordering = ['id', ]\n\n\nclass OrganisationLocation(BaseLocation):\n    location_target = models.ForeignKey('Organisation', related_name='locations')\n    iati_country = ValidXMLCharField(\n        _(u'country'), blank=True, max_length=2, choices=codelist_choices(COUNTRY, show_code=False),\n        help_text=_(u'The country in which the organisation is located.')\n    )\n\n    def iati_country_value(self):\n        return codelist_value(Country, self, 'iati_country')\n\n    def iati_country_value_unicode(self):\n        return unicode(self.iati_country_value())\n\n\nclass ProjectLocation(BaseLocation):\n    location_target = models.ForeignKey('Project', related_name='locations')\n\n    # Additional IATI fields\n    reference = ValidXMLCharField(\n        _(u'reference'), blank=True, max_length=50,\n        help_text=_(u'An internal reference that describes the location in the reporting '\n                    u'organisation\\'s own system. For reference see: '\n                    u'<a href=\"http://iatistandard.org/202/activity-standard/iati-activities/'\n                    u'iati-activity/location/#attributes\" target=\"_blank\">'\n                    u'http://iatistandard.org/202/activity-standard/iati-activities/iati-activity/'\n                    u'location/#attributes</a>.')\n    )\n    location_code = ValidXMLCharField(\n        _(u'code'), blank=True, max_length=25,\n        help_text=_(u'Enter a code to identify the region. Codes are based on DAC region codes. '\n                    u'Where an activity is considered global, the code 998 can be used. For '\n                    u'reference: <a href=\"http://www.oecd.org/dac/stats/dacandcrscodelists.htm\" '\n                    u'target=\"_blank\">http://www.oecd.org/dac/stats/dacandcrscodelists.htm</a>.')\n    )\n    vocabulary = ValidXMLCharField(_(u'vocabulary'), blank=True, max_length=2,\n                                   choices=codelist_choices(GEOGRAPHIC_VOCABULARY))\n    name = ValidXMLCharField(\n        _(u'name'), blank=True, max_length=100,\n        help_text=_(u'The human-readable name for the location.')\n    )\n    description = ValidXMLCharField(\n        _(u'location description'), blank=True, max_length=2000,\n        help_text=_(u'This provides free text space for providing an additional description, if '\n                    u'needed, of the actual target of the activity. A description that qualifies '\n                    u'the location, not the activity.')\n    )\n    activity_description = ValidXMLCharField(\n        _(u'activity description'), blank=True, max_length=2000,\n        help_text=_(u'A description that qualifies the activity taking place at the location. '\n                    u'This should not duplicate information provided in the main activity '\n                    u'description, and should typically be used to distinguish between activities '\n                    u'at multiple locations within a single iati-activity record.')\n    )\n    exactness = ValidXMLCharField(\n        _(u'location precision'), blank=True, max_length=1,\n        choices=codelist_choices(GEOGRAPHIC_EXACTNESS),\n        help_text=_(u'Defines whether the location represents the most distinct point reasonably '\n                    u'possible for this type of activity or is an approximation due to lack of '\n                    u'more detailed information.')\n    )\n    location_reach = ValidXMLCharField(\n        _(u'reach'), blank=True, max_length=1, choices=codelist_choices(GEOGRAPHIC_LOCATION_REACH),\n        help_text=_(u'Does this location describe where the activity takes place or where the '\n                    u'intended beneficiaries reside?')\n    )\n    location_class = ValidXMLCharField(\n        _(u'class'), blank=True, max_length=1, choices=codelist_choices(GEOGRAPHIC_LOCATION_CLASS),\n        help_text=_(u'Does the location refer to a physical structure such as a building, a '\n                    u'populated place (e.g. city or village), an administrative division, or '\n                    u'another topological feature (e.g. river, nature reserve)? For reference: '\n                    u'<a href=\"http://iatistandard.org/202/codelists/GeographicLocationClass/\" '\n                    u'target=\"_blank\">http://iatistandard.org/202/codelists/'\n                    u'GeographicLocationClass/</a>.')\n    )\n    feature_designation = ValidXMLCharField(\n        _(u'feature designation'), blank=True, max_length=5,\n        choices=codelist_choices(LOCATION_TYPE),\n        help_text=_(u'A more refined coded classification of the type of feature referred to by '\n                    u'this location. For reference: <a href=\"http://iatistandard.org/202/codelists/'\n                    u'LocationType/\" target=\"_blank\">http://iatistandard.org/202/codelists/'\n                    u'LocationType/</a>.')\n    )\n\n    def iati_country(self):\n        return codelist_value(Country, self, 'country')\n\n    def iati_country_unicode(self):\n        return unicode(self.iati_country())\n\n    def iati_vocabulary(self):\n        return codelist_value(GeographicVocabulary, self, 'vocabulary')\n\n    def iati_vocabulary_unicode(self):\n        return unicode(self.iati_vocabulary())\n\n    def iati_exactness(self):\n        return codelist_value(GeographicExactness, self, 'exactness')\n\n    def iati_exactness_unicode(self):\n        return unicode(self.iati_exactness())\n\n    def iati_reach(self):\n        return codelist_value(GeographicLocationReach, self, 'location_reach')\n\n    def iati_reach_unicode(self):\n        return unicode(self.iati_reach())\n\n    def iati_class(self):\n        return codelist_value(GeographicLocationClass, self, 'location_class')\n\n    def iati_class_unicode(self):\n        return unicode(self.iati_class())\n\n    def iati_designation(self):\n        return codelist_value(LocationType, self, 'feature_designation')\n\n    def iati_designation_unicode(self):\n        return unicode(self.iati_designation())\n\n\n# Over-riding fields doesn't work in Django < 1.10, and hence this hack.\nProjectLocation._meta.get_field('country').help_text = _(\n    u'The country or countries that benefit(s) from the activity.'\n)\n\n\nclass AdministrativeLocation(models.Model):\n    location = models.ForeignKey(\n        'ProjectLocation', verbose_name=_(u'location'), related_name='administratives'\n    )\n    code = ValidXMLCharField(\n        _(u'administrative code'), blank=True, max_length=25,\n        help_text=_(u'Coded identification of national and sub-national divisions according to '\n                    u'recognised administrative boundary repositories. Multiple levels may be '\n                    u'reported.')\n    )\n    vocabulary = ValidXMLCharField(\n        _(u'administrative vocabulary'), blank=True, max_length=2,\n        choices=codelist_choices(GEOGRAPHIC_VOCABULARY),\n        help_text=_(u'For reference: <a href=\"http://iatistandard.org/202/codelists/'\n                    u'GeographicVocabulary/\" target=\"_blank\">http://iatistandard.org/202/codelists/'\n                    u'GeographicVocabulary/</a>.')\n    )\n\n    level = models.PositiveSmallIntegerField(_(u'administrative level'), blank=True, null=True)\n\n    def __unicode__(self):\n        return unicode(self.code) if self.code else u'%s' % _(u'No code specified')\n\n    def iati_vocabulary(self):\n        return codelist_value(GeographicVocabulary, self, 'vocabulary')\n\n    def iati_vocabulary_unicode(self):\n        return unicode(self.iati_vocabulary())\n\n    class Meta:\n        app_label = 'rsr'\n        verbose_name = _(u'location administrative')\n        verbose_name_plural = _(u'location administratives')\n\n\nclass ProjectUpdateLocation(BaseLocation):\n    location_target = models.ForeignKey('ProjectUpdate', related_name='locations')\n", "path": "akvo/rsr/models/location.py"}]}