I have created a CustomUser(AbstractUser) Model and in this model I want to add email id field in admin Add User Page.Currently By default first we can enter username and Password and after creating username and password we are redirected to another page where email field is available I want this email field on add User page is this possible.?
On admin django already had a BaseUserAdmin which is the default, it have 2 parts, add form and change form which both forms created from fieldsets(change form) and add_fieldsets(add form)
To add fields or remove field on add form override the BaseUserAdmin add_fieldsets:
from django.contrib.auth.admin import UserAdmin
class CustomUserAdmin(UserAdmin):
add_fieldsets = UserAdmin.add_fieldsets + (
(None, {'fields': ('email',)}),
)
If you are using a custom ModelAdmin which is a subclass of
django.contrib.auth.admin.UserAdmin, then you need to add your custom
fields to fieldsets (for fields to be used in editing users) and to
add_fieldsets (for fields to be used when creating a user)
second method: override add_fieldsets attribute itself:
class CustomUserAdmin(UserAdmin):
# add_fieldsets is not a standard ModelAdmin attribute. UserAdmin
# overrides get_fieldsets to use this attribute when creating a user.
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('username', 'email', 'password1', 'password2'),
}),
)
Document: https://docs.djangoproject.com/en/3.1/topics/auth/customizing/#custom-users-and-django-contrib-admin
In admin.py of your app, create a ModelAdmin and use the fields attribute to include the email field in the view.
Example:
from django.contrib import admin
from myproject.myapp.models import CustomUser
class CustomUserAdmin(admin.ModelAdmin):
fields = ('username', 'password', 'email')
admin.site.register(CustomUser,CustomUserAdmin)
Related
I have inherited the user class to make custom authentication. I do not get password hashing this way. It just stores as plain text in MySQL database. I have created staff through admin panel and unable to login as staff. Furthermore I have also created auth API endpoints using DRF and Djoser and am unable to login with the user profiles created through Django admin panel.
Here is my code.
models.py
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
pass
admin.py
from .models import User
class UserAdmin(admin.ModelAdmin):
pass
admin.site.register(User, UserAdmin)
I have seen old replies in Stack Overflow suggesting changing the parent class to django.contrib.auth.admin.UserAdmin . When I try this the add user template form only has 3 fields. Username, Password and Password Confirmation.
admin.py
from django.contrib.auth.admin import UserAdmin as DefaultUserAdmin
from .models import User
class UserAdmin(DefaultUserAdmin):
pass
admin.site.register(User, UserAdmin)
How do I solve this problem.
I wrote a custom UserAdmin as well so i guess i can help you a little bit with that
try this one:
#admin.register(User)
class UserAdmin(UserAdmin):
"""Define admin model for custom User model with no email field."""
fieldsets = (
(None, {'fields': ('email', 'password')}),
(_('Personal info'), {'fields': ('first_name', 'last_name')}),
(_('Permissions'), {'fields': ('is_active', 'is_staff', 'is_superuser')}),
)
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('email', 'password1', 'password2'),
}),
)
list_display = ('email', 'is_staff')
search_fields = ('email',)
ordering = ('email',)
And i also think that there`s problems in your models.py bcs you dont have userManager
UserManager uses when you`re creating user so i guess problem in that
In my project, I use the AbstractUser class to override the default User model so I can add extra properties. I want these properties to be added to the admin page, therefore I can view them. The code below is how I have customized my admin page so far.
forms.py:
class CustomUserCreationForm(UserCreationForm):
class Meta:
model = User
fields = ('username', 'email', 'following', 'posts')
class CustomUserChangeForm(UserChangeForm):
class Meta:
model = User
fields = ('username', 'email', 'following', 'posts', )
admin.py:
class CustomUserAdmin(UserAdmin):
add_form = CustomUserCreationForm
form = CustomUserChangeForm
model = User
list_display = ['username', 'email', 'bio', 'profilePic',]
admin.site.register(User, CustomUserAdmin)
When I click on a user object on the admin page, I can view all the properties such as a users username and email, however I want to view properties such as following and posts, which are both ManyToManyFields.
I supply these properties in the CustomUserCreationForm and the CustomUserChangeForm, however I can't still view these properties.
Does anybody know how I can view these fields when I view or create a new user object? Thank you.
I've created custom model Profile and linked it to the User model which works fine. But, now I want to create custom UserCreateForm in Django admin. I redefined it and added necessary fields, but after that still shows, all fields from profile model, ex: phone, home_address. I need fields displayed as : 'first_name', 'last_name', 'username', 'password1', 'password2' in the UserCreateForm. What have I done wrong?
from django.contrib import admin
from django.contrib.auth.models import User
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.forms import UserCreationForm
from .models import Profile
class NewUserCreateForm(UserCreationForm):
class Meta:
fields = ('username', 'first_name', 'last_name',)
class ProfileInline(admin.TabularInline):
model = Profile
class UserAdmin(UserAdmin):
add_form = NewUserCreateForm
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('first_name', 'last_name', 'username','password1', 'password2', ),
}),
)
inlines = [ProfileInline]
admin.site.unregister(User)
admin.site.register(User, UserAdmin)
Firstly your models.py file will be :
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
class Profile(models.Model):
user_id = models.OneToOneField(User, on_delete=models.CASCADE)
phone = models.CharField(max_length=100)
address = models.CharField(max_length=256)
...
Then your admin.py file.
from.models import Profile
# Register your models here.
class ProfileAdmin(admin.ModelAdmin):
model = Profile
exclude = ['phone',] # Or whatever you don't want to display.
admin.site.register(Profile, ProfileAdmin)
For extended implementation please add or remove based on your needs.
Hope it helps.
I have a User model (stock django), linked with a UserProfile via a OneToOneField. Is it possible to display data from the UserProfile in the admin, when displaying users in tabular view?
I am doing:
class UserAdmin(UserAdmin):
inlines = (UserprofileInline,)
list_display = (
'username', 'email', 'first_name', 'last_name', 'is_staff'
)
# Re-register UserAdmin
admin.site.unregister(User)
admin.site.register(User, UserAdmin)
How can I extend the list_display parameter to specify fields belonging to the UserProfile?
For example if you have an address field in UserProfile model then you can do like this
class UserAdmin(UserAdmin):
inlines = (UserprofileInline,)
list_display = (
'username', 'email', 'first_name', 'last_name', 'is_staff','address'
)
def address(self,obj):
return obj.userprofile.address
You can register your extended model 'UserProfile' to the admin site.
In that model, you can show your fields from OneToOneField User model.
Please check this out:
One to One Field Django Admin
I extend the django user model as described in the dev doc. I wan't to keep most of the original User model features so I extend the AbstractUser class. I've defined in settings.py:
AUTH_USER_MODEL = 'myapp.CustomUser'
My user class:
class CustomUser(AbstractUser):
custom_field = models.ForeignKey('OtherModel')
objects = UserManager()
Everything seems to work fine but when I try to make it managed by the admin site:
admin.site.register(CustomUser, UserAdmin)
I get this error on the admin CustomUser creation page (after validation of the password confirmation form):
AttributeError: Manager isn't available; User has been swapped for 'myapp.CustomUser'
The point is that I need this model managed by the admin site in order to have the same creation process as with the original User model (two step process with password validation).
You need only change form for adding user(overwrite clean_username and change User on get_user_model()
Full working example(If you inherited from AbstractUser)
from django.contrib.auth import get_user_model
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
class MyUserChangeForm(UserChangeForm):
class Meta:
model = get_user_model()
class MyUserCreationForm(UserCreationForm):
class Meta:
model = get_user_model()
def clean_username(self):
username = self.cleaned_data["username"]
try:
get_user_model().objects.get(username=username)
except get_user_model().DoesNotExist:
return username
raise forms.ValidationError(self.error_messages['duplicate_username'])
class MyUserAdmin(UserAdmin):
form = MyUserChangeForm
add_form = MyUserCreationForm
fieldsets = (
(None, {'fields': [('username', 'password'),]}),
(_('Personal info'), {'fields': ('first_name', 'last_name', 'email')}),
(_('Permissions'), {'fields': ('is_active', 'is_staff', 'is_superuser',
'groups', 'user_permissions')}),
(_('Important dates'), {'fields': ('last_login', 'date_joined')}),
)
admin.site.register(MyUser, MyUserAdmin)
I struggled with this error for hours. For me I needed to remove all references to
from django.contrib.auth.models import User
and then replace it with:
from myapp.models import MyUser as User
This is assuming your custom User model is in an app called myapp and you called the model MyUser.
I'm using as User so that I don't have to change where my existing code that makes reference to the the User object from django.contrib.auth.models.
Good luck!
Alan
#aviars
You probably should look at full example in official documentation:
https://docs.djangoproject.com/en/dev/topics/auth/customizing/#a-full-example
There are some uncovered questions (permissions handling, for example), but, at least, it's working.
From Django docs:
You should also define a custom manager for your User model.
Subclass AbstractUser already handle objects = UserManager() for you (this code on github at line 327). You don't need to define it in your model again.
I'm not sure why it come with that error. But below config seem work for me with latest Dev version.
Model.py:
class CustomUser(AbstractUser):
custom_field = models.ForeignKey('OtherModel')
# remove : objects = UserManager()
I've found a solution:
I don't use UserAdmin to register the CustomUser in the admin site, I use a custom ModelAdmin.
class CustomUserAdmin(admin.ModelAdmin):
add_form = CustomUserCreationAdminForm
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('username', 'password1', 'password2')}
),
)
def get_fieldsets(self, request, obj=None):
if not obj:
return self.add_fieldsets
return super(CustomUserAdmin, self).get_fieldsets(request, obj)
def get_form(self, request, obj=None, **kwargs):
defaults = {}
if obj is None:
defaults.update({
'form': self.add_form,
'fields': admin.util.flatten_fieldsets(self.add_fieldsets),
})
defaults.update(kwargs)
return super(CustomUserAdmin, self).get_form(request, obj, **defaults)
Because I want to have a creation form different from the update form, I override the get_form function of the Model Admin as done in the UserAdmin django code. I also have created a custom Creation form for my custom user: CustomUserCreationForm
I received a response in the django-users mailing list that may be better than mine:
Unregister the original User class from the admin site and then register the CustomUser with UserAdmin:
admin.site.unregister(User)
admin.site.register(CustomUser, UserAdmin)
Not tested yet.
EDIT: this last solution doesn't work
Regards
UserAdmin is already registered to manage User, at the end of contrib/auth/admin.py
admin.site.register(User, UserAdmin)
Given you want to register UserAdmin with CustomUser, I think you would first have to unregister the User/UserAdmin pair:
admin.site.unregister(User)
then register your new model. Given the lack of control in the order of module loading, you could create a class derived from UserAdmin and manage your user model with it. This would work everytime, if I'm thinking properly.