localization.py 4.28 KB
Newer Older
1
from django.db import models
Florent Chehab's avatar
Florent Chehab committed
2
from rest_framework import serializers, viewsets, permissions
3

Florent Chehab's avatar
Florent Chehab committed
4
5
6
7
8
9
10
11
12
# Data model based on : https://unstats.un.org/unsd/methodology/m49/overview/


class Region(models.Model):
    name = models.CharField(max_length=200)
    un_code = models.CharField(primary_key=True, max_length=3)
    parent = models.ForeignKey(
        'self', on_delete=models.SET_NULL, null=True)

13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
    def r_type(self):
        p = 0
        region = self
        while region.parent is not None:
            p += 1
            region = region.parent

        if p is 0:
            return "main"
        elif p is 1:
            return "sub"
        elif p is 2:
            return "inter"
        else:
            raise Exception("Impossible case found")

Florent Chehab's avatar
Florent Chehab committed
29

30
class Country(models.Model):
31
    name = models.CharField(max_length=200)
Florent Chehab's avatar
Florent Chehab committed
32
33
34
    iso_alpha3_code = models.CharField(primary_key=True, max_length=3)
    region = models.ForeignKey(Region, on_delete=models.PROTECT, null=True)

35
36
37
38
39
40
41
42
    def get_regions(self):
        regions = [None] * 3
        regions.append(self.region)
        while regions[-1] is not None and regions[-1].parent is not None:
            regions.append(regions[-1].parent)
        regions = regions[::-1]
        return regions[0:3]

Florent Chehab's avatar
Florent Chehab committed
43

Florent Chehab's avatar
Florent Chehab committed
44
45
46
47
48
49
50
51
52
class City(models.Model):
    name = models.CharField(max_length=200)
    local_name = models.CharField(max_length=200, null=True)
    # We add an area to distinguish similarly named cities
    # in a country
    area = models.CharField(max_length=200, null=True)
    country = models.ForeignKey(Country, on_delete=models.PROTECT)


Florent Chehab's avatar
Florent Chehab committed
53
54
55
"""
API RELATED STUFF BELLOW
"""
Florent Chehab's avatar
Florent Chehab committed
56
57


Florent Chehab's avatar
Florent Chehab committed
58
59
60
61
class CountrySerializer(serializers.ModelSerializer):
    regions = serializers.SerializerMethodField()

    def get_regions(self, obj):
62
63
64
65
66
67
68
69
70
71
72
73
        regions = obj.get_regions()

        def get_info(i):
            r = regions[i]
            r_code = r.un_code if r is not None else None
            return {"code": r_code,
                    "url": self.get_region_url(regions[i])}
        res = {}
        res["main"] = get_info(0)
        res["sub"] = get_info(1)
        res["inter"] = get_info(2)
        return res
Florent Chehab's avatar
Florent Chehab committed
74
75
76
77
78
79
80
81
82
83
84

    def get_region_url(self, region):
        if region is None:
            return None

        return serializers.HyperlinkedRelatedField(
            view_name='country-detail',
            read_only=True) \
            .get_url(region, view_name='region-detail',
                     request=self.context['request'], format=None)

Florent Chehab's avatar
Florent Chehab committed
85
86
    class Meta:
        model = Country
Florent Chehab's avatar
Florent Chehab committed
87
        fields = ('name', 'iso_alpha3_code',
88
                  'region', 'regions')
Florent Chehab's avatar
Florent Chehab committed
89
90
91
92
93
94


class CountryViewSet(viewsets.ModelViewSet):
    permission_classes = (permissions.DjangoModelPermissions,)
    queryset = Country.objects.all()  # noqa: E1101
    serializer_class = CountrySerializer
Florent Chehab's avatar
Florent Chehab committed
95
96


Florent Chehab's avatar
Florent Chehab committed
97
98
class RegionSerializer(serializers.ModelSerializer):
    parent_url = serializers.SerializerMethodField()
99
    region_type = serializers.SerializerMethodField()
Florent Chehab's avatar
Florent Chehab committed
100
101
102
103
104
105
106
107
108
109
110

    def get_parent_url(self, obj):
        if obj.parent is None:
            return None

        return serializers.HyperlinkedRelatedField(
            view_name='country-detail',
            read_only=True) \
            .get_url(obj.parent, view_name='region-detail',
                     request=self.context['request'], format=None)

111
112
113
    def get_region_type(self, obj):
        return obj.r_type()

Florent Chehab's avatar
Florent Chehab committed
114
115
    class Meta:
        model = Region
116
        fields = ('name', 'un_code', 'parent', 'parent_url', 'region_type')
Florent Chehab's avatar
Florent Chehab committed
117
118
119
120
121
122


class RegionViewSet(viewsets.ModelViewSet):
    permission_classes = (permissions.DjangoModelPermissions,)
    queryset = Region.objects.all()  # noqa: E1101
    serializer_class = RegionSerializer
Florent Chehab's avatar
Florent Chehab committed
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143


class CitySerializer(serializers.ModelSerializer):
    country_url = serializers.SerializerMethodField()

    def get_country_url(self, obj):
        return serializers.HyperlinkedRelatedField(
            view_name='country-detail',
            read_only=True) \
            .get_url(obj.country, view_name='region-detail',
                     request=self.context['request'], format=None)

    class Meta:
        model = City
        fields = ('name', 'local_name', 'area', 'country', 'country_url')


class CityViewSet(viewsets.ModelViewSet):
    permission_classes = (permissions.DjangoModelPermissions,)
    queryset = City.objects.all()  # noqa: E1101
    serializer_class = CitySerializer