¿Cómo puedo tener el proceso de un solo paso de registro de usuario de Django (en lugar de dos pasos) con correo electrónico obligatorio?

Quiero que Django envíe un correo electrónico a la dirección de correo electrónico del usuario con detalles de inicio de sesión una vez que el administrador agregue un nuevo usuario al sitio de administración. Así que intenté usar las señales de Django para eso, pero el registro de usuario de Django es un proceso de dos pasos. Las señales se notifican en el primer paso. Función única y llamada de correo electrónico sin dirección de correo electrónico (que viene en el segundo paso). Mi código de señal:

def email_new_user(sender, **kwargs): if kwargs["created"]: # only for new users new_user = kwargs["instance"] send_mail('Subject here', 'Here is the message.', 'from@example.com',['to@example.com'], fail_silently=False) post_save.connect(email_new_user, sender=User) 

Entonces, lo que intenté superar este problema. Uso este código en admin.py

 class UserAdmin(admin.ModelAdmin): list_display = ('username', 'email', 'first_name', 'last_name', 'date_joined', 'last_login') search_fields = ['username', 'email'] filter_horizontal = ('user_permissions',) admin.site.unregister(User) admin.site.register(User, UserAdmin) 

Esto hace que todo el proceso de registro sea un proceso de un solo paso y que mis señales comiencen a funcionar y envíen correos a user_id en la adición de un nuevo usuario.

1. La contraseña del usuario no se convierte en hash y está visible al entrar en el formulario, lo que hace que el usuario no pueda iniciar sesión en el sitio de administración.

2.El campo de correo electrónico en el formulario no es obligatorio, lo que quiero que sea obligatorio.

Por favor, ayúdame 🙁

[EDITAR]

 I tried your code But I m still at same place where i was before posting this question. the code i used in my admin.py is: from django.contrib import admin from mysite.naturefarms.models import * from django.contrib.auth.models import User,Group from django.contrib.auth.admin import UserAdmin from django.contrib.auth.forms import UserCreationForm, UserChangeForm from django import forms from django.contrib.admin.views.main import * class MyUserCreationForm(UserCreationForm): class Meta: model = User fields = ('username', 'email',) class UserAdmin(admin.ModelAdmin): add_form = MyUserCreationForm admin.site.unregister(User) class MyUserAdmin(UserAdmin): add_form = MyUserCreationForm add_fieldsets = ( (None, { 'classes': ('wide',), 'fields': ('username', 'email', 'password1', 'password2')} ), ) admin.site.register(User, MyUserAdmin) 

Esta es la salida que estoy obteniendo al usar este código, que incluso no está convirtiendo el campo de contraseña en hash.

Si busca en django.contrib.auth admin.py, verá que la clase UserAdmin especifica la forma add_form como UserCreationForm.

UserCreationForm solo incluye el campo ‘nombre de usuario’ del modelo de usuario.

Ya que está proporcionando su propio UserAdmin, puede anular el add_form a un UserCreationForm personalizado que incluye los campos que necesita para que su señal funcione correctamente.

Espero que te ayude.

[Editar]

Aquí está el UserCreationForm de contrib.auth forms.py:

 class UserCreationForm(forms.ModelForm): """ A form that creates a user, with no privileges, from the given username and password. """ username = forms.RegexField(label=_("Username"), max_length=30, regex=r'^[\w.@+-]+$', help_text = _("Required. 30 characters or fewer. Letters, digits and @/./+/-/_ only."), error_messages = {'invalid': _("This value may contain only letters, numbers and @/./+/-/_ characters.")}) 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 = ("username",) def clean_username(self): username = self.cleaned_data["username"] try: User.objects.get(username=username) except User.DoesNotExist: return username raise forms.ValidationError(_("A user with that username already exists.")) def clean_password2(self): password1 = self.cleaned_data.get("password1", "") password2 = self.cleaned_data["password2"] if password1 != password2: raise forms.ValidationError(_("The two password fields didn't match.")) 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 

Observe los campos = (“nombre de usuario”,) tupla que excluye todos los demás campos en el modelo de usuario. Necesitas algo como:

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

entonces puede usar eso como add_form en su UserAdmin personalizado:

 class UserAdmin(admin.ModelAdmin): add_form = MyUserCreationForm 

Es bastante tarde en mi parte del mundo, pero veré si puedo conseguir una muestra de trabajo para usted mañana.

[Editar]

Ok, aquí están los cambios necesarios que necesitarás hacer para que esto funcione. Lo he probado usando Django 1.3:

 from django.contrib.auth.forms import UserCreationForm from django.contrib.auth.admin import UserAdmin from django.contrib.auth.models import User from django import forms admin.site.unregister(User) class MyUserAdmin(UserAdmin): add_form = MyUserCreationForm add_fieldsets = ( (None, { 'classes': ('wide',), 'fields': ('username', 'email', 'password1', 'password2')} ), ) admin.site.register(User, MyUserAdmin) 

No vi que el UserAdmin tenía una propiedad add_fieldset inicialmente. Es por eso que el campo de correo electrónico no se mostraba en el formulario de agregar.

Desde este ejemplo, intente definir el correo electrónico en su UserCreationForm personalizado según sea necesario = Verdadero:

 class MyUserCreationForm(UserCreationForm): email = forms.EmailField(required=True) class Meta: model = User fields = ('username', 'email',)