Source code for eucrim.users.models

# SPDX-FileCopyrightText: 2024 Thomas Breitner <t.breitner@csl.mpg.de>
#
# SPDX-License-Identifier: EUPL-1.2

from django.db import models
from django.forms.models import model_to_dict
from django.contrib.auth.models import AbstractUser

from .profile_management import user_tasks


[docs] class CustomUser(AbstractUser): """ CustomUser model for eucrim users with additional attributes. See also: http://docs.wagtail.io/en/v2.0.1/advanced_topics/customisation/custom_user_models.html """ EDITOR_IN_CHIEF = "10_EIC" MANAGING_DIRECTOR = "20_MDR" EDITOR = "30_EDT" EDITORIAL_BOARD = "40_EDB" LANGUAGE_CONSULTANT = "50_LCN" TYPESET = "60_TYS" WEB = "70_WEB" STUDENT_ASSISTANT = "80_SAS" EDITORIAL_ASSISTENT = "90_EAS" NOROLE = "99_NRL" # the last role is the default "no-role" and should not be printed out # in the templates TEAM_ROLE_CHOICES = ( (EDITOR_IN_CHIEF, "Editor in Chief"), (MANAGING_DIRECTOR, "Managing Editor"), (EDITOR, "Editor"), (EDITORIAL_BOARD, "Editorial Board"), (LANGUAGE_CONSULTANT, "Language Consultant"), (TYPESET, "Typeset"), (WEB, "Developer"), (STUDENT_ASSISTANT, "Student Assistent"), (EDITORIAL_ASSISTENT, "Editorial Assistent"), (NOROLE, "no role"), ) is_association_manager = models.BooleanField( default=False, help_text="If set, this user is designated to edit association data. " "No profile page is created. The user is informed about his " "new possibilities via email.", ) is_author = models.BooleanField( default=True, help_text="If set, an Author page will be created for this user.", ) is_team = models.BooleanField( default=False, help_text="If set, only a small subset of the AuthorPage fields " "will be used. Team members are found in the printed issue " "in the imprint.", ) team_role = models.CharField( max_length=6, choices=TEAM_ROLE_CHOICES, default=NOROLE, help_text="Role in eucrim team, like stated in the imprint of the " 'printed issue; e.g. "Managing Editor", defaults to a quasi ' 'non-role "Member"', ) @property def get_profilepage(self): from eucrim.profile.models import ProfilePage try: profile_page = ProfilePage.objects.get(user=self) except ProfilePage.DoesNotExist: profile_page = None return profile_page
[docs] @classmethod def from_db(cls, db, field_names, values): """ Get old values from db. see: https://docs.djangoproject.com/el/2.1/ref/models/instances/#customizing-model-loading """ instance = super().from_db(db, field_names, values) instance._loaded_values = dict(zip(field_names, values)) return instance
[docs] def save(self, *args, **kwargs): """ Custom model save method to trigger some tasks. We need to know if this instance is a new or modified one, we need to know if certain fields have changed (e.g. if user had not is_author flag but does has now, we need to create a ProfilePage for him). So we are interessted in the fields that have changed and their new value. """ FIELDS_TO_MONITOR = { "is_team", "is_author", "is_association_manager", } if self._state.adding: user_state_action = "created" else: user_state_action = "modified" if self._state.adding: fields_changed = dict() else: # only check for changed fields when not adding a completly new # user instance fields_loaded = { _key: self._loaded_values[_key] for _key in FIELDS_TO_MONITOR } fields_new = model_to_dict(self, fields=FIELDS_TO_MONITOR) # comparing two sets, using difference(), here with the "-" notation fields_changed = set(fields_new.items()) - set(fields_loaded.items()) fields_changed = dict(fields_changed) # Calling save in order to get the pk: super().save(*args, **kwargs) # Custom logic for creating and updateing corresponding ProfilePage # instances: # TODO: refactor user_tasks(self, user_state_action, fields_changed)