Создание нового пользователя со случайным паролем в django

#django #django-views #django-forms #django-authentication #django-users

#django #django-просмотры #django-формы #django-аутентификация #django-пользователи

Вопрос:

Я работал над проектом, в котором администратор регистрирует пользователей для использования веб-сайта. скажем, в моем случае администратор регистрирует учителей и учащихся школы. Мне нужен какой-то способ создать случайный пароль для каждого нового пользователя, и электронное письмо будет отправлено с использованием зарегистрированного электронного письма с паролем. Я использую пользовательскую модель пользователя.

 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(), но, похоже, это не сработало.

Ответ №1:

Форма .save() принимает необязательный commit аргумент ключевого слова, если вы вызовете save() с commit=False , то он вернет объект, который еще не был сохранен в базе данных. Вы можете изменить данные, а затем сохранить их.

 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>
 

Комментарии:

1. Я попробовал описанный выше способ. Там написано keyerror. причина в том, что в методе UserRegisterForm я удалил поля пароля, так как я не хочу, чтобы они отображались во время регистрации. Но метод сохранения ищет поля password1 и password2

2. @swasthiknayak самый простой способ, о котором я мог подумать, — это использовать hidden input добавление двух дополнительных input полей в рендеринг вашей формы, после чего он успешно пройдет этап проверки формы

3. Но {{форма}} сама создаст поля пароля, и к ним будет предпринята попытка доступа.