From df244e47cd3b51188a0d43bd76379c24703427d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felipe=20Marti=CC=81n?= Date: Tue, 4 Nov 2014 23:01:44 +0100 Subject: [PATCH] Migrated users app to account app Added custom user model (closes #39) --- config/requirements.txt | 1 - .../apps/{users => account}/__init__.py | 0 .../{users => account}/context_processors.py | 1 + shelfzilla/apps/{users => account}/forms.py | 0 shelfzilla/apps/account/models.py | 137 ++++++++++++++++++ shelfzilla/apps/{users => account}/urls.py | 2 +- shelfzilla/apps/{users => account}/views.py | 0 shelfzilla/apps/homepage/views.py | 6 +- .../apps/users/fixtures/initial_data.json | 10 -- shelfzilla/apps/users/models.py | 15 -- shelfzilla/settings/base.py | 15 +- shelfzilla/urls.py | 2 +- 12 files changed, 152 insertions(+), 37 deletions(-) rename shelfzilla/apps/{users => account}/__init__.py (100%) rename shelfzilla/apps/{users => account}/context_processors.py (99%) rename shelfzilla/apps/{users => account}/forms.py (100%) create mode 100644 shelfzilla/apps/account/models.py rename shelfzilla/apps/{users => account}/urls.py (88%) rename shelfzilla/apps/{users => account}/views.py (100%) delete mode 100644 shelfzilla/apps/users/fixtures/initial_data.json delete mode 100644 shelfzilla/apps/users/models.py diff --git a/config/requirements.txt b/config/requirements.txt index 0f609b2..9cdc129 100644 --- a/config/requirements.txt +++ b/config/requirements.txt @@ -8,7 +8,6 @@ django-solo==1.1.0 django-import-export==0.2.6 # Fixes -longerusername==0.4 # Statics django-compressor==1.4 diff --git a/shelfzilla/apps/users/__init__.py b/shelfzilla/apps/account/__init__.py similarity index 100% rename from shelfzilla/apps/users/__init__.py rename to shelfzilla/apps/account/__init__.py diff --git a/shelfzilla/apps/users/context_processors.py b/shelfzilla/apps/account/context_processors.py similarity index 99% rename from shelfzilla/apps/users/context_processors.py rename to shelfzilla/apps/account/context_processors.py index 1279d83..adf7efb 100644 --- a/shelfzilla/apps/users/context_processors.py +++ b/shelfzilla/apps/account/context_processors.py @@ -22,6 +22,7 @@ def user_configuration(request): }, } + def auth(request): result = {} if request.user.is_authenticated(): diff --git a/shelfzilla/apps/users/forms.py b/shelfzilla/apps/account/forms.py similarity index 100% rename from shelfzilla/apps/users/forms.py rename to shelfzilla/apps/account/forms.py diff --git a/shelfzilla/apps/account/models.py b/shelfzilla/apps/account/models.py new file mode 100644 index 0000000..a75d518 --- /dev/null +++ b/shelfzilla/apps/account/models.py @@ -0,0 +1,137 @@ +# coding: utf-8 +from hashlib import md5 + +from django.db import models +from django.utils import timezone +from django.contrib.auth.models import UserManager +from django.contrib.auth.models import (AbstractBaseUser, PermissionsMixin) +from django.utils.translation import ugettext_lazy as _ + + +class User(AbstractBaseUser, + PermissionsMixin): + """ + + """ + MALE = 'male' + FEMALE = 'female' + GENDER_CHOICES = ( + (MALE, _('Male')), + (FEMALE, _('Female')) + ) + + @property + def avatar(self): + avatar = '{}{}?s=300'.format( + 'http://www.gravatar.com/avatar/', + md5(self.email.lower()).hexdigest() + ) + return avatar + + email = models.EmailField( + verbose_name=_('Email address'), + max_length=255, + unique=True, + db_index=True, + help_text=_('An user email that should be verified.') + ) + + username = models.CharField( + verbose_name=_('Username'), + max_length=128, + unique=True, + blank=True, + null=True, + db_index=True, + default=None, + ) + + # personal info + first_name = models.CharField( + verbose_name=_('First name'), + max_length=80, blank=True, default='', + ) + + last_name = models.CharField( + verbose_name=_('Last name'), + max_length=80, blank=True, default='', + ) + + birthdate = models.DateField( + verbose_name=_('Birthdate'), + null=True, + blank=True, + default=None, + ) + + gender = models.CharField( + verbose_name=_('Gender'), + max_length=80, + choices=GENDER_CHOICES, + blank=True, + default='' + ) + + date_joined = models.DateTimeField( + verbose_name=_('Date joined'), + auto_now_add=True, + editable=False, + ) + + is_active = models.BooleanField( + verbose_name=_('Active status'), + default=True, + help_text=_('Designates whether this user should be treated as ' + 'active. Unselect this instead of deleting accounts.') + ) + + is_staff = models.BooleanField( + verbose_name=_('Staff status'), + default=False, + help_text=_('Designates whether the user can log into this admin ' + 'site.') + ) + + USERNAME_FIELD = 'username' + REQUIRED_FIELDS = ('email', ) + + objects = UserManager() + + class Meta: + verbose_name = _('User') + + def __unicode__(self): + return self.username + + @property + def is_confirmed(self): + return self.CONFIRMED == self.status + + @property + def full_name(self): + return '{first_name} {last_name}'.format( + first_name=self.first_name.strip(), + last_name=self.last_name.strip() + ) + + @property + def age(self): + """Age of the user + + Returns the age of the user if she has a defined birthdate. + """ + if self.birthdate is None: + return None + else: + today = timezone.now() + birthdate = self.birthdate + try: + birthdate.replace(year=today.year) + except ValueError: + # Raises only with 29th February and current not leap year + birthdate_day = 28 + else: + birthdate_day = birthdate.day + return today.year - birthdate.year - ( + (today.month, today.day) < (birthdate.month, birthdate_day) + ) diff --git a/shelfzilla/apps/users/urls.py b/shelfzilla/apps/account/urls.py similarity index 88% rename from shelfzilla/apps/users/urls.py rename to shelfzilla/apps/account/urls.py index 6722565..1ca2633 100644 --- a/shelfzilla/apps/users/urls.py +++ b/shelfzilla/apps/account/urls.py @@ -1,6 +1,6 @@ from django.conf.urls import patterns, url -from .views import LoginView, LogoutView,UserProfileView +from .views import LoginView, LogoutView, UserProfileView urlpatterns = patterns( '', diff --git a/shelfzilla/apps/users/views.py b/shelfzilla/apps/account/views.py similarity index 100% rename from shelfzilla/apps/users/views.py rename to shelfzilla/apps/account/views.py diff --git a/shelfzilla/apps/homepage/views.py b/shelfzilla/apps/homepage/views.py index c7d8597..9d0b921 100644 --- a/shelfzilla/apps/homepage/views.py +++ b/shelfzilla/apps/homepage/views.py @@ -2,7 +2,7 @@ from django.views.generic import View from django.template import RequestContext from django.shortcuts import render_to_response from django.db.models import Count -from shelfzilla.apps.users.models import User +from django.contrib.auth import get_user_model from shelfzilla.apps.manga.models import Volume, Series @@ -13,7 +13,7 @@ class HomepageView(View): data = {} from datetime import datetime # TOP 5 - data['TOP_5_COLLECTORS'] = User.objects.filter(pk__gt=1)\ + data['TOP_5_COLLECTORS'] = get_user_model().objects.filter(pk__gt=1)\ .annotate(num_volumes=Count('have_volumes'))\ .order_by('-num_volumes')[:5] @@ -29,7 +29,7 @@ class HomepageView(View): # Stats data['STATS'] = { - 'users': User.objects.count() - 1, + 'users': get_user_model().objects.count() - 1, 'series': Series.objects.count(), 'series_review': Series.objects.filter(for_review=True).count(), 'volumes': Volume.objects.count(), diff --git a/shelfzilla/apps/users/fixtures/initial_data.json b/shelfzilla/apps/users/fixtures/initial_data.json deleted file mode 100644 index 6cd973f..0000000 --- a/shelfzilla/apps/users/fixtures/initial_data.json +++ /dev/null @@ -1,10 +0,0 @@ -[ - { - "pk": 1, - "model": "auth.group", - "fields": { - "name": "Beta Access", - "permissions": [] - } - } -] diff --git a/shelfzilla/apps/users/models.py b/shelfzilla/apps/users/models.py deleted file mode 100644 index 8529d92..0000000 --- a/shelfzilla/apps/users/models.py +++ /dev/null @@ -1,15 +0,0 @@ -from hashlib import md5 -from django.contrib.auth.models import User as UserModel - - -class User(UserModel): - @property - def avatar(self): - avatar = '{}{}?s=300'.format( - 'http://www.gravatar.com/avatar/', - md5(self.email.lower()).hexdigest() - ) - return avatar - - class Meta: - proxy = True diff --git a/shelfzilla/settings/base.py b/shelfzilla/settings/base.py index 360e6f7..b4e541c 100644 --- a/shelfzilla/settings/base.py +++ b/shelfzilla/settings/base.py @@ -32,14 +32,13 @@ ALLOWED_HOSTS = [] # Application definition INSTALLED_APPS = ( - 'longerusername', - # Admin 'suit', 'django.contrib.admin', 'solo', # Django + 'shelfzilla.apps.account', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', @@ -63,7 +62,6 @@ INSTALLED_APPS = ( # Apps 'shelfzilla.apps._admin', 'shelfzilla.apps.config', - 'shelfzilla.apps.users', 'shelfzilla.apps.homepage', 'shelfzilla.apps.landing', 'shelfzilla.apps.manga', @@ -85,9 +83,9 @@ TEMPLATE_CONTEXT_PROCESSORS = ( 'shelfzilla.apps.manga.context_processors.user_have_volumes', 'shelfzilla.apps.manga.context_processors.user_wishlisted_volumes', 'shelfzilla.apps.manga.context_processors.user_read_volumes', - 'shelfzilla.apps.users.context_processors.auth', - 'shelfzilla.apps.users.context_processors.user_is_staff', - 'shelfzilla.apps.users.context_processors.user_configuration', + 'shelfzilla.apps.account.context_processors.auth', + 'shelfzilla.apps.account.context_processors.user_is_staff', + # 'shelfzilla.apps.account.context_processors.user_configuration', ) MIDDLEWARE_CLASSES = ( @@ -292,3 +290,8 @@ CKEDITOR_CONFIGS = { 'width': '100%', }, } + +# +# AUTH +# +AUTH_USER_MODEL = 'account.User' diff --git a/shelfzilla/urls.py b/shelfzilla/urls.py index 35e6566..06e02b2 100644 --- a/shelfzilla/urls.py +++ b/shelfzilla/urls.py @@ -13,7 +13,7 @@ urlpatterns = patterns( url(r'^messages/$', MessagesView.as_view(), name="contrib.messages"), url(r'^$', include('shelfzilla.apps.homepage.urls')), url(r'^', include('shelfzilla.apps.landing.urls')), - url(r'^', include('shelfzilla.apps.users.urls')), + url(r'^', include('shelfzilla.apps.account.urls')), url(r'^blog/', include('shelfzilla.apps.blog.urls', namespace='blog')), url(r'^series/', include('shelfzilla.apps.manga.urls.series')), url(r'^volumes/', include('shelfzilla.apps.manga.urls.volumes')),