university.py 4.3 KB
Newer Older
Florent Chehab's avatar
Florent Chehab committed
1
2
import logging

3
from django.db import models
4
from django.core.validators import MinValueValidator, MaxValueValidator
5

Florent Chehab's avatar
Florent Chehab committed
6
from backend_app.fields import JSONField
7
8
9
10
11
from backend_app.models.abstract.essentialModule import (
    EssentialModule,
    EssentialModuleSerializer,
    EssentialModuleViewSet,
)
12
from backend_app.models.file_picture import Picture
13
from backend_app.permissions.moderation import ModerationLevels
14
from backend_app.models.country import Country
Florent Chehab's avatar
Florent Chehab committed
15

Florent Chehab's avatar
Florent Chehab committed
16
17
logger = logging.getLogger("django")

18

19
class University(EssentialModule):
20
21
22
    """
    Model storing information about universities
    """
23

24
25
    moderation_level = ModerationLevels.ENFORCED

26
    name = models.CharField(max_length=200)
27
    acronym = models.CharField(max_length=20, default="", blank=True)
28
    logo = models.ForeignKey(Picture, null=True, on_delete=models.PROTECT)
29
    website = models.URLField(default="", blank=True, max_length=300)
30

31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
    city = models.CharField(max_length=200)
    country = models.ForeignKey(Country, on_delete=models.PROTECT)

    main_campus_lat = models.DecimalField(
        max_digits=10,
        decimal_places=6,
        validators=[MinValueValidator(-85.05112878), MaxValueValidator(85.05112878)],
    )

    main_campus_lon = models.DecimalField(
        max_digits=10,
        decimal_places=6,
        validators=[MinValueValidator(-180), MaxValueValidator(180)],
    )

Florent Chehab's avatar
Florent Chehab committed
46
47
48
    # a bit of denormalization
    denormalized_infos = JSONField(default=dict)

49
50
51
    def location(self):
        return {"lat": self.main_campus_lat, "lon": self.main_campus_lon}

52

53
class UniversitySerializer(EssentialModuleSerializer):
54
55
    class Meta:
        model = University
56
57
58
59
60
        fields = EssentialModuleSerializer.Meta.fields + (
            "name",
            "acronym",
            "logo",
            "website",
61
62
63
64
            "city",
            "country",
            "main_campus_lat",
            "main_campus_lon",
Florent Chehab's avatar
Florent Chehab committed
65
            "denormalized_infos",
66
        )
Florent Chehab's avatar
Florent Chehab committed
67
68


69
class UniversityViewSet(EssentialModuleViewSet):
70
    permission_classes = EssentialModuleViewSet.permission_classes
71
72
    serializer_class = UniversitySerializer
    queryset = University.objects.all()  # pylint: disable=E1101
73
    end_point_route = "universities"
Florent Chehab's avatar
Florent Chehab committed
74
75
76
77


def update_denormalized_univ_field():
    logger.info("Computing the denormalized offers/semester/major in university")
78
79
80
    for university in University.objects.all().prefetch_related(
        "offers", "exchanges", "corresponding_utc_partners"
    ):
81
        semesters_majors_minors = dict()
82

Florent Chehab's avatar
Florent Chehab committed
83
84
85
        # handling of offers
        for offer in university.offers.all():
            semester = "{}{}".format(offer.semester, offer.year)
86
87
            if semester not in semesters_majors_minors.keys():
                semesters_majors_minors[semester] = dict()
Florent Chehab's avatar
Florent Chehab committed
88
89
90
91
92
93
94
            majors = offer.majors
            if majors is not None:
                possibilities = set(
                    map(lambda s: s.lstrip().rstrip(), majors.split(","))
                )
                for major in possibilities:
                    # No minors in offers
95
                    semesters_majors_minors[semester][major] = list()
Florent Chehab's avatar
Florent Chehab committed
96
97
98
99

        # handling of exchanges
        for exchange in university.exchanges.all():
            semester = "{}{}".format(exchange.semester, exchange.year)
100
101
            if semester not in semesters_majors_minors.keys():
                semesters_majors_minors[semester] = dict()
Florent Chehab's avatar
Florent Chehab committed
102
103
104
            major = exchange.student_major
            minor = exchange.student_minor
            if major is not None:
105
106
                if major not in semesters_majors_minors[semester].keys():
                    semesters_majors_minors[semester][major] = list()
Florent Chehab's avatar
Florent Chehab committed
107
108
                if (
                    minor is not None
109
                    and minor not in semesters_majors_minors[semester][major]
Florent Chehab's avatar
Florent Chehab committed
110
                ):
111
                    semesters_majors_minors[semester][major].append(minor)
Florent Chehab's avatar
Florent Chehab committed
112

113
114
115
116
117
118
119
120
121
122
123
124
        # handling of corresponding_utc_partners
        id_destination_open = (
            university.corresponding_utc_partners.filter(
                is_destination_open=True
            ).count()
            > 0
        )

        university.denormalized_infos = dict(
            id_destination_open=id_destination_open,
            semesters_majors_minors=semesters_majors_minors,
        )
Florent Chehab's avatar
Florent Chehab committed
125
126
127
        university.save()

    logger.info("Done the denormalized offers/semester/major in university")