【问题标题】:Creating new user with random password in django在 django 中使用随机密码创建新用户
【发布时间】:2021-03-16 15:20:54
【问题描述】:

我一直在做一个管理员注册用户使用网站的项目。就我而言,管理员注册学校的教师和学生。我需要一些方法为每个新用户创建随机密码,并且将使用带有密码的注册电子邮件发送一封电子邮件。我正在使用自定义用户模型。

class MyAccountManager(BaseUserManager):
    def create_user(self, email, username, password=None):
        if not email:
            raise ValueError("Users must have email Id")
        if not username:
            raise ValueError("Users must have an username")


        user = self.model(email=self.normalize_email(email),
                          username=username)
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self, email, username, password=None):
        user = self.create_user(email=self.normalize_email(email),
                                username=username,
                                password=password)
        user.role = 'ADM'
        user.is_admin = True
        user.is_staff = True
        user.is_superuser = True
        user.save(using=self._db)
        return user


class User(AbstractUser):
    email = models.EmailField(verbose_name="Email", unique=True)
    ROLE_CHOICES = [
        ('STD', 'STUDENT'),
        ('THR', 'TEACHER'),
        ('ADM', 'ADMIN')
    ]
    role = models.CharField(max_length=3, choices=ROLE_CHOICES, default='STD')
    username = models.CharField(max_length=50, unique=True)
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)
    date_of_birth = models.DateField(null=True)
    description = models.TextField(null=True)
    image = models.ImageField(default='default.jpg', upload_to='profile_pics')

    date_joined = models.DateTimeField(verbose_name="date joined", auto_now_add=True)
    last_login = models.DateTimeField(verbose_name="last login", auto_now=True)
    is_admin = models.BooleanField(default=False)
    is_staff = models.BooleanField(default=False)
    is_superuser = models.BooleanField(default=False)

    USERNAME_FIELD = 'username'
    REQUIRED_FIELDS = ['email']

    objects = MyAccountManager()

这里是我的注册视图。

@login_required
def register(request):
    if not request.user.is_superuser:
        return HttpResponse('Unauthorized', status=401)
    if request.method == 'POST':
        form = UserRegisterForm(request.POST)

        if form.is_valid():
            username = form.cleaned_data.get('username')
            email = form.cleaned_data.get('email')
            password = User.objects.make_random_password(length=10,
                                                         allowed_chars='abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789')
            form.save()
            user = User.objects.filter(username=username)
            user.set_password(password)
            user.save()
            send_mail(
                'Login details',
                'Here is your login details \n username : ' + username + '\n password : ' + password,
                from_email=None,
                recipient_list=[email],
                fail_silently=False,
            )
            messages.success(message="Email has been sent to " + email + ".")
            return redirect('register')
    else:

        form = UserRegisterForm()
    return render(request, 'users/register.html', {'form': form})

这是我的用户注册表格

class UserRegisterForm(UserCreationForm):
    email = forms.EmailField(required=True)

    def __init__(self, *args, **kwargs):
        super(UserCreationForm, self).__init__(*args, **kwargs)
        del self.fields['password1']
        del self.fields['password2']

    class Meta:
        model = User
        fields = ['username', 'email', 'role']

我可以通过哪些方式进行设置。我尝试通过覆盖 form.save() 似乎没有工作。

【问题讨论】:

    标签: django django-views django-forms django-authentication django-users


    【解决方案1】:

    表单.save() 接受可选的commit 关键字参数,如果您使用commit=False 调用save(),那么它将返回一个尚未保存到数据库的对象。您可以修改数据然后保存。

    def register(request):
        ...
        f = UserRegisterForm(request.POST)
        if f.is_valid():
            u = f.save(commit=False)
            raw_password = User.objects.make_random_password(...)
            u.set_password(raw_password)
            u.save()
        ...
    

    模板

    <form action="..." method="post">
        {% csrf_token %}
        {{ form }}
        <input type="password" name="password1" value="random_value" hidden>
        <input type="password" name="password2" value="random_value" hidden>
        <input type="submit" value="Submit">
    </form>
    

    【讨论】:

    • 我试过上面的方法。它说keyerror。由于在 UserRegisterForm 方法中,我已删除密码字段,因为我不希望在注册期间显示它们。但是 save 方法会查找字段 password1 和 password2
    • @swasthiknayak 我能想到的最简单的方法是使用hidden input,在表单渲染中添加两个额外的input 字段,然后它将成功通过表单验证阶段
    • 但是 {{form}} 将自己创建密码字段并尝试访问。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-06-11
    • 1970-01-01
    • 1970-01-01
    • 2015-06-27
    • 2018-12-20
    • 2011-06-02
    • 2016-06-06
    相关资源
    最近更新 更多