Skip to content

Instantly share code, notes, and snippets.

@aruseni
Last active October 19, 2017 18:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aruseni/6a4e257ffbfa0218a1436b45a555f03a to your computer and use it in GitHub Desktop.
Save aruseni/6a4e257ffbfa0218a1436b45a555f03a to your computer and use it in GitHub Desktop.
Substituting Django User model
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from django.utils.translation import ugettext_lazy as _
from .forms import UserChangeForm, UserCreationForm
from .models import User
class AdminSite(admin.AdminSite):
site_header = _("Header")
admin_site = AdminSite(name="admin")
class MyUserAdmin(UserAdmin):
form = UserChangeForm
add_form = UserCreationForm
list_display = ("email", "date_joined", "is_staff")
list_filter = (
"is_staff",
"is_superuser",
"is_active",
"groups",
)
fieldsets = (
(None, {"fields": ("email", "password")}),
(_("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")}
),
)
search_fields = ("email",)
ordering = ("email",)
admin_site.register(User, MyUserAdmin)
from django import forms
from django.contrib.auth.forms import ReadOnlyPasswordHashField
from django.contrib.auth import password_validation
from django.utils.translation import ugettext_lazy as _
from .models import User
class UserCreationForm(forms.ModelForm):
"""
A form that creates a user, with no privileges,
from the given email and password.
"""
error_messages = {
"password_mismatch": _("The two password fields didn't match."),
}
password1 = forms.CharField(
label=_("Password"),
strip=False,
widget=forms.PasswordInput,
help_text=password_validation.password_validators_help_text_html(),
)
password2 = forms.CharField(
label=_("Password confirmation"),
widget=forms.PasswordInput,
strip=False,
help_text=_("Enter the same password as before, for verification."),
)
class Meta:
model = User
fields = ("email",)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if self._meta.model.USERNAME_FIELD in self.fields:
self.fields[self._meta.model.USERNAME_FIELD].widget.attrs.update(
{"autofocus": True}
)
def clean_password2(self):
password1 = self.cleaned_data.get("password1")
password2 = self.cleaned_data.get("password2")
if password1 and password2 and password1 != password2:
raise forms.ValidationError(
self.error_messages["password_mismatch"],
code="password_mismatch",
)
return password2
def _post_clean(self):
super()._post_clean()
# Validate the password after self.instance is updated with form data
# by super().
password = self.cleaned_data.get("password2")
if password:
try:
password_validation.validate_password(password, self.instance)
except forms.ValidationError as error:
self.add_error("password2", error)
def save(self, commit=True):
user = super().save(commit=False)
user.set_password(self.cleaned_data["password1"])
if commit:
user.save()
return user
class UserChangeForm(forms.ModelForm):
password = ReadOnlyPasswordHashField(
label=_("Password"),
help_text=_(
"Raw passwords are not stored, so there is no way to see this "
"user's password, but you can change the password using "
"<a href=\"{}\">this form</a>."
),
)
class Meta:
model = User
fields = "__all__"
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields[
"password"
].help_text = self.fields["password"].help_text.format("../password/")
f = self.fields.get("user_permissions")
if f is not None:
f.queryset = f.queryset.select_related("content_type")
def clean_password(self):
# Regardless of what the user provides, return the initial value.
# This is done here, rather than on the field, because the
# field does not have access to the initial value
return self.initial["password"]
from django.db import models
from django.contrib.auth.models import (
BaseUserManager,
AbstractBaseUser,
PermissionsMixin,
)
from django.utils.translation import ugettext_lazy as _
from django.utils import timezone
class MyUserManager(BaseUserManager):
def _create_user(self, email, password, **extra_fields):
"""
Creates and saves a User with the given email and password.
"""
if not email:
raise ValueError("The email address must be set")
email = self.normalize_email(email)
user = self.model(email=email, **extra_fields)
user.set_password(password)
user.save(using=self._db)
return user
def create_user(self, email=None, password=None, **extra_fields):
extra_fields.setdefault("is_staff", False)
extra_fields.setdefault("is_superuser", False)
return self._create_user(email, password, **extra_fields)
def create_superuser(self, email, password, **extra_fields):
extra_fields.setdefault("is_staff", True)
extra_fields.setdefault("is_superuser", True)
if extra_fields.get("is_staff") is not True:
raise ValueError("Superuser must have is_staff=True.")
if extra_fields.get("is_superuser") is not True:
raise ValueError("Superuser must have is_superuser=True.")
return self._create_user(email, password, **extra_fields)
class User(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(_("email address"), unique=True)
is_staff = models.BooleanField(
_("staff status"),
default=False,
help_text=_(
"Designates whether the user can log into this admin site."
),
)
is_active = models.BooleanField(
_("active"),
default=True,
help_text=_(
"Designates whether this user should be treated as active. "
"Unselect this instead of deleting accounts."
),
)
date_joined = models.DateTimeField(_("date joined"), default=timezone.now)
objects = MyUserManager()
USERNAME_FIELD = "email"
EMAIL_FIELD = "email"
def get_full_name(self):
return self.email
def get_short_name(self):
return self.email
def __str__(self):
return self.email
class Meta:
verbose_name = _("user")
verbose_name_plural = _("users")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment