localization.py 3.27 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
44
45
46

"""
API RELATED STUFF BELLOW
"""
Florent Chehab's avatar
Florent Chehab committed
47
48


Florent Chehab's avatar
Florent Chehab committed
49
50
51
52
class CountrySerializer(serializers.ModelSerializer):
    regions = serializers.SerializerMethodField()

    def get_regions(self, obj):
53
54
55
56
57
58
59
60
61
62
63
64
        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
65
66
67
68
69
70
71
72
73
74
75

    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
76
77
    class Meta:
        model = Country
Florent Chehab's avatar
Florent Chehab committed
78
        fields = ('name', 'iso_alpha3_code',
79
                  'region', 'regions')
Florent Chehab's avatar
Florent Chehab committed
80
81
82
83
84
85


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


Florent Chehab's avatar
Florent Chehab committed
88
89
class RegionSerializer(serializers.ModelSerializer):
    parent_url = serializers.SerializerMethodField()
90
    region_type = serializers.SerializerMethodField()
Florent Chehab's avatar
Florent Chehab committed
91
92
93
94
95
96
97
98
99
100
101

    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)

102
103
104
    def get_region_type(self, obj):
        return obj.r_type()

Florent Chehab's avatar
Florent Chehab committed
105
106
    class Meta:
        model = Region
107
        fields = ('name', 'un_code', 'parent', 'parent_url', 'region_type')
Florent Chehab's avatar
Florent Chehab committed
108
109
110
111
112
113


class RegionViewSet(viewsets.ModelViewSet):
    permission_classes = (permissions.DjangoModelPermissions,)
    queryset = Region.objects.all()  # noqa: E1101
    serializer_class = RegionSerializer