Source code for cuedmembers.models

from django.conf import settings
from django.db import models

from django.contrib.auth import get_user_model

[docs]class Division(models.Model): """ A division within CUED. The primary key for a division is actually its letter, A-F. .. attribute:: letter The Divisional ID letter, A-F. .. attribute:: name A human-readable name for the Division. """ letter = models.CharField(max_length=1, primary_key=True) name = models.CharField(max_length=256) def __str__(self): return self.letter
[docs]class ResearchGroup(models.Model): """ A research group in CUED. .. attribute:: division The :py:class:`.Division` which this research group is a part of. .. attribute:: name A human-readable name for the Research Group. """ division = models.ForeignKey(Division, related_name='research_groups') name = models.CharField(max_length=256) def __str__(self): return
[docs]class MemberManager(models.Manager): """ A specialised Manager for :py:class:`.Member` instances. """
[docs] def update_or_create_by_crsid(self, crsid, defaults=None): """ Retrieve or create a new member from a crsid. If a corresponding user does not exist, it is created. The newly created user has set_unusable_password() called on it and is added to the database. The first_name, last_name and email entries in defaults are set on the corresponding user and any other values are set on the member. See the update_or_create() documentation for discussion of the defaults parameter. """ defaults = defaults if defaults is not None else {} user_keys = set(('first_name', 'last_name', 'email')) u_defaults = dict( (k, v) for k, v in defaults.items() if k in user_keys) m_defaults = dict( (k, v) for k, v in defaults.items() if k not in user_keys) u, _ = get_user_model().objects.update_or_create( username=crsid, defaults=u_defaults) u.set_unusable_password() m, m_created = self.update_or_create(user=u, defaults=m_defaults) return m, m_created
[docs] def active(self): """A query-set of active users.""" return self.filter(is_active=True)
[docs] def inactive(self): """A query-set of inactive users.""" return self.filter(is_active=False)
[docs]class Member(models.Model): """ An extension of the standard Django User to indicate that a particular user is a member of the Department. There is a one-to-one mapping of Users to Members however not every User is necessarily a Member. .. note:: While there is nothing stopping you adding a foreign-key to a Member in models, its better to add a foreign-key to a User. That way you app's models are decoupled from relying on the CUED membership database and may be of wider user. The "Surname" and "Preferred name" fields from the Department are mapped through to the associated User's ``last_name`` and ``first_name``. The "First names" provided by the Department are stored in this model. An "active" member is currently present at CUED. Information in this model is expected to be provided by the Department. See for some discussion of what the fields mean. Note that is_active is the primary means by which one should judge if a Member is currently a member of the Department. This model does not include role/course, host/supervisor, room number or phone number. The "arrived" flag is folded into the is_active field. .. attribute:: user The :py:class:`django.contrib.auth.models.User` associated with this Member. .. attribute:: first_names A string containing the first names for the member supplied by the Department. Although it is tempting to use a space as a separator for these, that way danger lies! .. attribute:: research_group The :py:class:`.ResearchGroup` which this member is a part of. .. attribute:: is_active Members are not usually deleted from the database. Instead they become "active" or "inactive". This is to allow for the same person to be considered *as* the same person if they leave CUED and then subsequently return. """ user = models.OneToOneField(settings.AUTH_USER_MODEL, related_name='cued_member') first_names = models.CharField(max_length=100, default='', blank=True) research_group = models.ForeignKey(ResearchGroup, null=True, related_name='members') is_active = models.BooleanField(default=True) objects = MemberManager() @property def crsid(self): """This member's CRSid. The CRSid is the username of the associated user. This property merely returns the ``username`` of the associated User. """ return self.user.username def __str__(self): return '{} ({})'.format(self.user.get_full_name(), self.crsid)