0

I have taken reference from https://github.com/DjangoGirls/djangogirls to create user model that user email instead of username. But at a super admin level, I want to add an email address and set activation flag and then send an email with a password setting link. Once the admin user clicks on the link and activates his account he should be able to login and start using the admin panel.

Any guidance would be highly appreciated... Thanks in advance..

Models.py

class UserManager(auth_models.BaseUserManager):
    def create_user(self, email, password=None):
        if email is None:
            raise TypeError('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):
      if password is None:
          raise TypeError('Superusers must have a password.')

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


class User(auth_models.AbstractBaseUser, auth_models.PermissionsMixin, TimestampedModel):
    email = models.EmailField(db_index=True, unique=True)
    first_name = models.CharField(max_length=30, blank=True)
    last_name = models.CharField(max_length=30, blank=True)
    is_staff = models.BooleanField(default=False, help_text='Allow the user access to the admin site')
    is_superuser = models.BooleanField(
        default=False,
        help_text='User has all permissions'
    )
    is_active = models.BooleanField(default=True)
    date_joined = models.DateTimeField(auto_now_add=True)
    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = []
    objects = UserManager()

    def __str__(self):
        return self.email

    # def __str__(self):
    #     if self.first_name == '' and self.last_name == '':
    #         return '{0}'.format(self.email)
    #     return '{0} ({1})'.format(self.get_full_name(), self.email)

    @property
    def token(self):
        return self._generate_jwt_token()

    def get_full_name(self):
        return "{0} {1}".format(self.first_name, self.last_name)

    def get_short_name(self):
        return self.first_name

    def _generate_jwt_token(self):

        dt = datetime.now() + timedelta(days=60)

        token = jwt.encode({
            'id': self.pk,
            'exp': int(dt.strftime('%s'))
        }, settings.SECRET_KEY, algorithm='HS256')

        return token.decode('utf-8')

    def generate_password(self):
        password = User.objects.make_random_password()
        self.set_password(password)
        self.save()
        return password

    def email_user(self, from_email=None):
        subject= "Welcome to the Site"
        message= "Your Credentials are {0} ({1})".format(self.email, self.password)

        from_email= settings.DEFAULT_FROM_EMAIL
        send_mail(subject, message, from_email, [self.email])
    class Meta:
        verbose_name="Site Admin"
        verbose_name_plural= 'Site Admins'

forms.py

class UserCreationForm(forms.ModelForm):
    error_messages = {
        'password_mismatch': "The two password fields didn't match.",
    }

    password1 = forms.CharField(label="Password", widget=forms.PasswordInput)
    password2 = forms.CharField(
        label="Password confirmation",
        widget=forms.PasswordInput,
        help_text="Enter the same password as above, for verification."
    )

    class Meta:
        model = User
        fields = ('email',)

    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 save(self, commit=True):
        user = super(UserCreationForm, self).save(commit=False)
        user.set_password(self.cleaned_data["password1"])
        if commit:
            user.save()
        return user
sk01
  • 55
  • 1
  • 6

1 Answers1

0

Without any code of your models.py it is hard to tell which options might be feasible. Assuming your User model has an email and a password field, both non-nullable and required, then you would have to provide an abitrary password in any case. You could use Django Password Generator as a first step, set the activation flag, send the email, and let the user do whatever you would like the user to do.

Hope that helps. For future questions please include specific code. :)

Cheers

Herbert
  • 108
  • 7
  • Thanks for the reply. I have edited my question with my model and form inputs. – sk01 Mar 11 '20 at 11:01
  • Thanks for the code. Here's my idea: You could modify your `create_superuser` function as follows: `def create_superuser(self, email, password=None): user = self.create_user(email, password=password) # Set all flags here if password is None: user.make_random_password() ` That should solve your issue. The reference can be found here: [Django Docs](https://docs.djangoproject.com/en/3.0/topics/auth/customizing/#django.contrib.auth.models.BaseUserManager.make_random_password) – Herbert Mar 12 '20 at 12:44
  • @sure Herbert.. Thanks alot .. Will give it a try if works will let you know – sk01 Mar 13 '20 at 10:48