I want Django to send an email to user email-address with Login details once admin adds a new user to admin site.So I tried using Django signals for that but just becoz django user registration is a two step process signals get notified in first step only and called email function without email address(which comes in second step). My signal code:
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.', '[email protected]',['[email protected]'], fail_silently=False)
post_save.connect(email_new_user, sender=User)
So what i tried to overcome this problem.I use this code in 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)
This makes all registration process a single step process and my signals start working and sending mail to user_id on new user addition.But the problem came after this were:
1. User password is not converted into hash and is visible while entering into form,that makes user not able to login into admin site.
2.Email field in form is not compulsory which I want to be compulsory.
Please help me :(
[EDIT]
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)
If you look in django.contrib.auth admin.py, you'll see that the UserAdmin class specifies the add_form as UserCreationForm.
UserCreationForm only includes the 'username' field from the User model.
Since you're providing your own UserAdmin, you can just override the add_form to a custom UserCreationForm that includes the fields you need to make your signal work properly.
Hope that helps you out.
[Edit]
Here's the UserCreationForm from 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
Notice the fields = ("username",) tuple which excludes all other fields on the User model. You need something like:
class MyUserCreationForm(UserCreationForm):
class Meta:
model = User
fields = ('username', 'email',)
then you can use that as the add_form in your custom UserAdmin:
class UserAdmin(admin.ModelAdmin):
add_form = MyUserCreationForm
It's pretty late in my part of the world, but I'll see if I can get a working sample for you tomorrow.
[Edit]
Ok, here's the necessary changes you'll need to make to make this work. I've tested it using 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)
I didn't see that the UserAdmin had an add_fieldset property initially. That's why the email field wasn't displaying in the add form.
From this example try defining email in your custom UserCreationForm as required=True:
class MyUserCreationForm(UserCreationForm):
email = forms.EmailField(required=True)
class Meta:
model = User
fields = ('username', 'email',)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With