Question

I use django 1.5.5, django registration 1.0

How can I create model that have no login field but use email field instead login?

I tried to use model without Login but django admin was crappy. I could not save or edit data or even add new user.

So I tried to copy username as email:

settings.py:

AUTH_USER_MODEL = 'custom_user.My_User'

INSTALLED_APPS = (
  ...
  'custom_user',
)

ACCOUNT_ACTIVATION_DAYS = 2
REGISTRATION_OPEN = True
AUTH_USER_EMAIL_UNIQUE = True

models.py:

#models.py
# -*- coding: utf-8 -*-

from django.utils import timezone

from django.core.mail import send_mail

from django.db import models

from django.contrib.auth.models import (
    BaseUserManager, AbstractBaseUser, PermissionsMixin
)

class My_User_UserManager(BaseUserManager):

    def create_user(self, 
                        username=None,
                        email=None,
                        password=None,

                        **extra_fields
                        ):


        if not email:
            msg = u'You must enter e-mail'
            raise ValueError(msg)

        username = email

        now = timezone.now()

        My_User = self.model(
            username=My_User_UserManager.normalize_email(email),
            email=My_User_UserManager.normalize_email(email),
            is_staff=False,
            is_active=True,
            is_superuser=False,
            last_login=now,
            date_joined=now,
            **extra_fields
        )
        My_User.set_password(password)
        My_User.save(using=self._db)
        return My_User

    def create_superuser(self,
                            email,
                            password,
                            **extra_fields
                            ):

        username = email

        u = self.create_user(
            username,
            email,
            password=password,
        )
        u.is_admin = True
        u.is_staff = True
        u.is_superuser = True
        u.save(using=self._db)
        return u

class My_User(AbstractBaseUser, PermissionsMixin):
    username = models.CharField(
        verbose_name=u'Login',
        max_length=50,
        unique=True,
        db_index=True,
        )

    email = models.EmailField(
        verbose_name=u'Email',
        unique=True,
        db_index=True,
        )

    date_joined = models.DateTimeField(u'date joined', default=timezone.now)

    USERNAME_FIELD = 'email'

    is_active = models.BooleanField(default=True)
    is_admin = models.BooleanField(default=False)
    is_staff = models.BooleanField(u'Stuff', default=False)

    objects = My_User_UserManager()

    def get_full_name(self):
        return self.email

    def get_short_name(self):
        return self.email

    def email_user(self, subject, message, from_email=None):
        """
        Sends an email to this User.
        """
        send_mail(subject, message, from_email, [self.email])

    def __unicode__(self):
        return self.email

admin.py:

# -*- coding: utf-8 -*-

from django import forms
from django.contrib import admin
from django.contrib.auth.forms import UserCreationForm, UserChangeForm

from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.forms import ReadOnlyPasswordHashField

from django.contrib.auth import get_user_model
User = get_user_model()


from .models import My_User
from .models import My_User_UserManager

class My_User_CreationForm(UserCreationForm):
    error_messages = {
        'duplicate_username': u'duplicate username',
        'duplicate_email': u'duplicate email',
        'password_mismatch': u'password mismatch',
    }

    password1 = forms.CharField(
        label=u'Password',
        widget=forms.PasswordInput)
    password2 = forms.CharField(
        label=u'Password 2',
        widget=forms.PasswordInput,
        help_text=u'Enter the same password')

    class Meta:
        model = get_user_model() 
        fields = ('username', 'email') 

    def clean_username(self):
        username = self.cleaned_data["username"]
        try:
            get_user_model().objects.get(username=username)
        except get_user_model().DoesNotExist:
            return username
        raise forms.ValidationError(self.error_messages['duplicate_username'])

    def clean_password2(self):
        # Check that the two password entries match
        password1 = self.cleaned_data.get("password1")
        password2 = self.cleaned_data.get("password2")
        if password1 and password2 and password1 != password2:
            msg = u"passwords isn't equal"
            raise forms.ValidationError(msg)
        return password2

    def save(self, commit=True):
        # Save the provided password in hashed format
        user = super(My_User_CreationForm,
                        self).save(commit=False)
        user.set_password(self.cleaned_data["password1"])
        if commit:
            user.save()
        return user


class My_User_ChangeForm(UserChangeForm):
    password = ReadOnlyPasswordHashField()

    class Meta:
        model = get_user_model()

    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"]


class My_User_Admin(UserAdmin):
    add_form = My_User_CreationForm
    form = My_User_ChangeForm

    list_display = (
                    'email',
                    'is_staff',
                    )

    list_filter = ('is_staff',
                    'is_superuser',
                    'is_active',
                    'groups',
                    )

    search_fields = (
                        'email',
                        )

    ordering = ('email',)

    filter_horizontal = ('groups',
                            'user_permissions',)

    fieldsets = (        
        (None, {'classes': ('wide',),
                                    'fields': 
                                    (
                                     'email',
                                     'password',
                                     'username',
                                     )}),

        (u'Права', {'classes': ('wide',),
                                'fields': ('is_active',
                                            'is_staff',
                                            'is_superuser',
                                            'groups',
                                            'user_permissions')}),

        (u'Важные даты', {'classes': ('wide',),
                                    'fields': ('last_login',
                                               'date_joined')}),
    )

    add_fieldsets = (
        (None, {
            'classes': ('wide',),
            'fields': (
                        'username',
                        'email',
                        'password1',
                        'password2',
                        )}
        ),
    )

admin.site.register(My_User, My_User_Admin)

Any suggestions?

Was it helpful?

Solution

Problem solved by using django-registration-email 0.7.1

Provides a custom authentication backend so that users can signup to the site via their email address instead of a username. Also provides a set of standard templates and sane URL mappings for the whole registration workflow.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top