-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 4480353
Showing
19 changed files
with
545 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
__pycache__ | ||
__version__.py | ||
.git | ||
.virtualenv | ||
.vscode | ||
*.log | ||
*.pyc | ||
*.sublime-project | ||
*.sublime-workspace | ||
*.swp | ||
*~ | ||
local.py | ||
media |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
default_app_config = 'apps.users.apps.UsersAppConfig' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
from django.contrib import admin | ||
from django.contrib.auth.admin import UserAdmin as DjangoUserAdmin | ||
from django.utils.translation import ugettext_lazy as _ | ||
|
||
from .forms import CustomUserChangeForm, CustomUserCreationForm | ||
from .models import User | ||
|
||
__all__ = ( | ||
'UserAdmin', | ||
) | ||
|
||
|
||
@admin.register(User) | ||
class UserAdmin(DjangoUserAdmin): | ||
"""User admin. | ||
Admin class definitions for ``User`` model. | ||
""" | ||
search_fields = ('first_name', 'last_name', 'email') | ||
list_display = ( | ||
'id', | ||
'email', | ||
'date_joined', | ||
'last_login', | ||
'is_active', | ||
'is_staff', | ||
'is_superuser' | ||
) | ||
list_display_links = ('email',) | ||
add_fieldsets = ( | ||
(None, { | ||
'classes': ('wide',), | ||
'fields': ('email', 'password1', 'password2'), | ||
}), | ||
) | ||
fieldsets = ( | ||
(None, {'fields': ('email', 'password')}), | ||
(_('Personal info'), { | ||
'fields': ( | ||
'first_name', | ||
'last_name', | ||
) | ||
}), | ||
(_('Permissions'), { | ||
'fields': ( | ||
'is_active', | ||
'is_staff', | ||
'is_superuser', | ||
'groups', | ||
'user_permissions' | ||
) | ||
}), | ||
(_('Important dates'), { | ||
'fields': ('last_login', 'date_joined') | ||
}), | ||
) | ||
add_fieldsets = ( | ||
(None, { | ||
'classes': ('wide',), | ||
'fields': ('email', 'password1', 'password2'), | ||
}), | ||
) | ||
readonly_fields = DjangoUserAdmin.readonly_fields + ( | ||
'last_login', | ||
'date_joined', | ||
) | ||
ordering = ('email',) | ||
form = CustomUserChangeForm | ||
add_form = CustomUserCreationForm |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
from django.apps import AppConfig | ||
|
||
|
||
class UsersAppConfig(AppConfig): | ||
"""Configuration for Users app.""" | ||
name = 'apps.users' | ||
verbose_name = 'Users' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
from django.contrib.auth.forms import UserChangeForm, UserCreationForm | ||
|
||
from .models import User | ||
|
||
__all__ = ('CustomUserChangeForm', 'CustomUserCreationForm') | ||
|
||
|
||
class CustomUserChangeForm(UserChangeForm): | ||
"""Custom change form for ``User`` model. | ||
This class overrides ``UserChangeForm`` to provide different ``User`` | ||
model in Meta. | ||
""" | ||
|
||
class Meta: | ||
model = User | ||
fields = '__all__' | ||
|
||
|
||
class CustomUserCreationForm(UserCreationForm): | ||
"""Custom creation form for ``User`` model. | ||
This class overrides ``UserCreationForm`` to provide different ``User`` | ||
model in Meta and also replaces ``username`` field with ``email`` field. | ||
""" | ||
|
||
class Meta: | ||
model = User | ||
fields = ('email',) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
from django.contrib.auth.models import BaseUserManager | ||
from django.utils.translation import ugettext_lazy as _ | ||
|
||
__all__ = ( | ||
'UserManager', | ||
) | ||
|
||
|
||
class UserManager(BaseUserManager): | ||
"""Custom user manager. | ||
The custom user manager needs instead base manager because we use | ||
``email`` instead ``username`` for authentication. | ||
""" | ||
|
||
def create_user(self, email, password=None): | ||
"""Create user. | ||
Overridden base user manager method, customized for auth with email | ||
instead username. | ||
""" | ||
|
||
if not email: | ||
raise ValueError(_("Users must have an email address!")) | ||
|
||
user = self.model(email=self.normalize_email(email),) | ||
|
||
user.set_password(password) | ||
user.save(using=self._db) | ||
|
||
return user | ||
|
||
def create_superuser(self, email, password): | ||
"""Create superuser. | ||
Overridden base user manager method, customized for auth with email | ||
instead username. | ||
""" | ||
user = self.create_user(email, password=password) | ||
|
||
user.is_superuser = True | ||
user.is_staff = True | ||
user.save(using=self._db) | ||
|
||
return user |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
# Generated by Django 2.2.3 on 2019-07-31 15:13 | ||
|
||
from django.db import migrations, models | ||
import django.utils.timezone | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
initial = True | ||
|
||
dependencies = [ | ||
('auth', '0011_update_proxy_permissions'), | ||
] | ||
|
||
operations = [ | ||
migrations.CreateModel( | ||
name='User', | ||
fields=[ | ||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | ||
('password', models.CharField(max_length=128, verbose_name='password')), | ||
('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')), | ||
('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')), | ||
('first_name', models.CharField(max_length=255, verbose_name='First name')), | ||
('last_name', models.CharField(max_length=255, verbose_name='Last name')), | ||
('email', models.EmailField(max_length=255, unique=True, verbose_name='Email')), | ||
('is_active', models.BooleanField(default=True, verbose_name='Is active')), | ||
('is_staff', models.BooleanField(default=False, help_text='The user will have access to admin interface.', verbose_name='Is staff')), | ||
('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='Date joined')), | ||
('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.Group', verbose_name='groups')), | ||
('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.Permission', verbose_name='user permissions')), | ||
], | ||
options={ | ||
'verbose_name': 'User', | ||
'verbose_name_plural': 'Users', | ||
'db_table': 'users', | ||
'ordering': ('email',), | ||
}, | ||
), | ||
] |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
from urllib.parse import urljoin | ||
|
||
from django.urls import reverse | ||
from django.conf import settings | ||
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin | ||
from django.contrib.postgres.fields import JSONField | ||
from django.db import models | ||
from django.utils import timezone | ||
from django.utils.translation import ugettext_lazy as _ | ||
|
||
from .managers import UserManager | ||
|
||
__all__ = ( | ||
'User', | ||
) | ||
|
||
|
||
class User(AbstractBaseUser, PermissionsMixin): | ||
"""Custom user model. | ||
Attributes: | ||
first_name (str): First name. | ||
last_name (str): Last, family name. | ||
email (str): E-mail, uses for authentication. | ||
is_active (bool): Can user log in to the system. | ||
is_staff (bool): Can user access to admin interface. | ||
date_joined (datetime): Date when the account was created. | ||
Nested attributes: | ||
is_superuser (bool): The user can super access to admin UI. | ||
groups(Manager): The groups this user belongs to. | ||
user_permissions(Manager): Specified permissions for this user. | ||
last_login (datetime): Last date when user login to the system. | ||
""" | ||
EMAIL_FIELD = 'email' | ||
USERNAME_FIELD = 'email' | ||
|
||
first_name = models.CharField( | ||
max_length=255, | ||
verbose_name=_("First name") | ||
) | ||
last_name = models.CharField( | ||
max_length=255, | ||
verbose_name=_("Last name") | ||
) | ||
email = models.EmailField( | ||
max_length=255, | ||
unique=True, | ||
verbose_name=_("Email") | ||
) | ||
is_active = models.BooleanField( | ||
default=True, | ||
verbose_name=_("Is active"), | ||
) | ||
is_staff = models.BooleanField( | ||
default=False, | ||
verbose_name=_("Is staff"), | ||
help_text=_("The user will have access to admin interface."), | ||
) | ||
date_joined = models.DateTimeField( | ||
default=timezone.now, | ||
verbose_name=_("Date joined"), | ||
) | ||
|
||
objects = UserManager() | ||
|
||
class Meta: | ||
db_table = 'users' | ||
ordering = ('email',) | ||
verbose_name = _("User") | ||
verbose_name_plural = _("Users") | ||
|
||
def __str__(self): | ||
return self.email | ||
|
||
def get_full_name(self): | ||
full_name = '{first_name} {last_name}'.format( | ||
first_name=self.last_name, | ||
last_name=self.first_name, | ||
) | ||
|
||
return full_name.strip() | ||
|
||
def get_short_name(self): | ||
return self.first_name | ||
|
||
def get_admin_change_url(self) -> str: | ||
"""Get admin change URL. | ||
Build full url (host + path) to standard Django admin page for | ||
object like: | ||
https://api.sitename.com/admin/users/user/234/ | ||
""" | ||
|
||
assert self.id, "Instance must have an ID" | ||
|
||
return urljoin( | ||
settings.DJANGO_SITE_BASE_HOST, | ||
reverse('admin:users_user_change', args=(self.id,)), | ||
) |
Empty file.
Empty file.
Oops, something went wrong.