Source code for invenio_userprofiles.models
# -*- coding: utf-8 -*-
#
# This file is part of Invenio.
# Copyright (C) 2015-2018 CERN.
#
# Invenio is free software; you can redistribute it and/or modify it
# under the terms of the MIT License; see LICENSE file for more details.
"""Database models for user profiles."""
from __future__ import absolute_import, print_function
from invenio_accounts.models import User
from invenio_db import db
from sqlalchemy import event
from sqlalchemy.ext.hybrid import hybrid_property
from .validators import validate_username
[docs]class AnonymousUserProfile():
"""Anonymous user profile."""
@property
def is_anonymous(self):
"""Return whether this UserProfile is anonymous."""
return True
[docs]class UserProfile(db.Model):
"""User profile model.
Stores a username, display name (case sensitive version of username) and a
full name for a user.
"""
__tablename__ = 'userprofiles_userprofile'
user_id = db.Column(
db.Integer,
db.ForeignKey(User.id),
primary_key=True
)
"""Foreign key to :class:`~invenio_accounts.models.User`."""
user = db.relationship(
User, backref=db.backref(
'profile', uselist=False, cascade='all, delete-orphan')
)
"""User relationship."""
_username = db.Column('username', db.String(255), unique=True)
"""Lower-case version of username to assert uniqueness."""
_displayname = db.Column('displayname', db.String(255))
"""Case preserving version of username."""
full_name = db.Column(db.String(255), nullable=False, default='')
"""Full name of person."""
@hybrid_property
def username(self):
"""Get username."""
return self._displayname
@username.setter
def username(self, username):
"""Set username.
.. note:: The username will be converted to lowercase. The display name
will contain the original version.
"""
validate_username(username)
self._username = username.lower()
self._displayname = username
[docs] @classmethod
def get_by_username(cls, username):
"""Get profile by username.
:param username: A username to query for (case insensitive).
"""
return cls.query.filter(
UserProfile._username == username.lower()
).one()
[docs] @classmethod
def get_by_userid(cls, user_id):
"""Get profile by user identifier.
:param user_id: Identifier of a :class:`~invenio_accounts.models.User`.
:returns: A :class:`~invenio_userprofiles.models.UserProfile` instance
or ``None``.
"""
return cls.query.filter_by(user_id=user_id).one_or_none()
@property
def is_anonymous(self):
"""Return whether this UserProfile is anonymous."""
return False
[docs]@event.listens_for(User, 'init')
def on_user_init(target, args, kwargs):
"""Provide hook on :class:`~invenio_accounts.models.User` initialization.
Automatically convert a dict to a
:class:`~.UserProfile` instance. This is needed
during e.g. user registration where Flask-Security will initialize a
user model with all the form data (which when Invenio-UserProfiles is
enabled includes a ``profile`` key). This will make the user creation fail
unless we convert the profile dict into a :class:`~.UserProfile` instance.
"""
profile = kwargs.pop('profile', None)
if profile is not None and not isinstance(profile, UserProfile):
profile = UserProfile(**profile)
if kwargs.get('id'):
profile.user_id = kwargs['id']
kwargs['profile'] = profile