How to customize Django admin page of Users - python

I was trying to customize Django (version 1.8) admin page of Users (which is under Authentication and Authorization on admin page), but I cannot get it to work.
Currently, the default admin page of Users shows 5 defaults fields: username, email address, first name, last name, staff status. And, I am trying to make the admin Users page show following fields: username, email. date_joined, last_login
So, I created admin.py file and saved it in the directory where wsgi.py is with the following code:
class UserAdmin(admin.ModelAdmin):
list_display = ("username", "email", "date_joined", "last_login")
class Meta:
model = User
admin.site.unregister(User)
admin.site.register(User, UserAdmin)
But, the code above did not force admin User page display the fields that I want it to display("username", "email", "date_joined", "last_login").
Then, I replaced the code above with the following code in admin.py:
class MyUserAdmin(UserAdmin):
list_display = ("username", "email", "date_joined", "last_login")
admin.site.unregister(User)
admin.site.register(User, MyUserAdmin)
But, no luck. There was a similar question on stackoverflow and answers to it (How to customize the auth.User Admin page in Django CRUD?), and above two blocks of code are what I was trying to do after reading the answers. But, I still cannot get it to work.
Can anyone help me?

I just found out what the problem was. The problem was that I did not include the app in INSTALLED_APPS in settings.

Related

Add fields from another model to the admin site

My Profile model has a OneToOne relation with Django's built-in User model.
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
verified = models.BooleanField(default=False)
If I want to change user's password or properties like Active or Superuser I have to do it in one Change User page, and to edit verified property I have to go to another.
Is there any way to merge this:
And this:
Into one form so I can edit everything about a user in one page?
Edit 1:
As you guys suggested the StackedInline approach, let's see how it turns out.
Please first look at Django's default Admin site (first screenshot above):
Everything is grouped in sections and sections have titles.
Look at how the password information is displayed.
There's a link to change the password.
Now I implement the StackedInline solution.
Please note that this is in the admin.py of my myapp:
from django.contrib import admin
from .models import Profile
from django.contrib.auth.models import User
# Register your models here.
class ProfileInline(admin.StackedInline):
model = Profile
class UserAdmin(admin.ModelAdmin):
inlines = (ProfileInline, )
admin.site.unregister(User)
admin.site.register(User, UserAdmin)
Now let's look at Admin site:
Everything is scattered. Sections and their titles are gone (Personal info, Permissions, etc).
Password field shows the hashed password. All other information is gone.
There's no link to change the password.
Edit 2:
To solve the problem of Edit 1 I look at the source code of Django (https://github.com/django/django/blob/main/django/contrib/auth/admin.py) and add update my code as below:
class UserAdmin(admin.ModelAdmin):
inlines = (ProfileInline, )
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")}),
)
add_fieldsets = (
(
None,
{
"classes": ("wide",),
"fields": ("username", "password1", "password2"),
},
),
)
filter_horizontal = (
"groups",
"user_permissions",
)
admin.site.unregister(User)
admin.site.register(User, UserAdmin)
Now I have two sections in the Admin site:
The section on the top shows almost everything (except that the password field is still different and there's no link to change the password and also the verified field is not there) but sections and titles are back.
Then there's this additional and completely unnecessary part:
As you can see:
All fields of information about the user is repeated
Look at the password field
Information is not grouped in sections with titles
verified filed appears.
OP can use one of the InlineModelAdmin objects such as StackedInline. This allows one to create inline forms providing one the ability to edit models on the same page as a parent model.
Adapting for OP's case, it would be something like
from django.contrib import admin
class ProfileInline(admin.StackedInline):
model = Profile
class UserAdmin(admin.ModelAdmin):
inlines = [
ProfileInline,
]
admin.site.register(User, UserAdmin)
Now OP's admin site is set up to edit Profile objects inline from the User detail page.
User model Extension vs Inheritance.
Your profile model only add some elements to user. In this case Model inheritance can be better.
# models.py
class Profile(user):
verified = models.BooleanField(default=False)
after that you can achieve all fields for user and for profile:
# admin.py
class ProfileAdmin(ModelAdmin):
fields = '__all__'
if you don't want to switch on Model inheritance.
You can use InlineModel in UserAdmin to change related model.
# admin.py
class ProfileInline(StackedInline):
model=Profile
class UserAdmin(ModelAdmin):
inlines = (ProfileInline, )
you can use override AbstractUser from model Django so you can merge user in one place like this:
from django.contrib.auth.models import AbstractUser
from django.db import models
class CustomUser(AbstractUser):
verified = models.BooleanField(default=False)
and you need to add this line to Django settings.py file so that Django knows to use the new User class:
AUTH_USER_MODEL = 'users.CustomUser'
then make sure to migrate :
(env)$ python manage.py makemigrations
(env)$ python manage.py migrate

Django "fields" attribute of user forms (UserCreationForm and UserChangeForm)

According to Django docs:
It is strongly recommended that you explicitly set all fields that should be edited in the form using the fields attribute.
I have a custom user model, so I overrode UserCreationForm and UserChangeForm, but I'm not sure about the fields attribute of the Meta class.
The admin site will be editing all fields of a user; so in UserChangeForm, do I have to include all fields in this attribute? like this:
class Meta:
model = User
fields = (
"email",
"password",
"is_active",
"is_staff",
"is_superuser",
"date_joined",
"last_login",
"groups",
"user_permissions",
# maybe there are others that I'm missing?
)
Or in this case, it's safe to use the '__all__' shortcut?
The admin site uses UserChangeForm for editing user attributes (including permissions and so); so these need to be included in the fields attribute. But does this mean using the UserChangeForm anywhere other than the admin site, causes those security issues mentioned in the docs?

Delete password, Last login, Superuser status, Groups, User permissions...filed in User tab in Django admin after clicking into a specific user

I have used Django2 and simpleUI to develop a Django web app.
Now I want to delete password, Last login, Superuser status, Groups, User permissions...filed in Django admin.
How could I do that? I tried to unregister my user and rewrite it, but failed to delete anything.
admin.py:
```python
from django.contrib import admin
from django.contrib.auth import forms
from .models import *
from django.contrib.auth.models import Permission
admin.site.register(User)
I have tried
class UserAdmin(admin.ModelAdmin):
list_display = ('email', 'first_name')
list_filter = ('is_staff', 'is_superuser')
admin.site.unregister(User)
admin.site.register(User, UserAdmin)
But it did not delete any thing when I click a specific user, still shows password, Last login, Date joined,blah blah, those kind of fields that boss want me to hide.
You can register another super user and chage any thing You want
python maange.py createsuperuser
you if you want to change password of any superuser
python manage.py changepassword (superuser_name)
you can delete sqlite database and startwith fresh form migrate
Override UserAdmin.
from django.contrib.auth.admin import UserAdmin
class CustomUserAdmin(UserAdmin):
"Declare your custom fields or fieldset here."
admin.site.register(User, CustomUserAdmin)

Storing new field to Django Admin "user" section from registration form

I have managed to add an additional field to the Registration form, "where did you hear about us?".
But I am not sure which files to edit in order to store the data from this field along with the users info.
i.e. When logging into the Admin section and go to "users" and view a users info I would like to see this field there.
Simplest way would be to store additional data in a UserProfile model about the user, e.g.
from django.contrib.auth.models import User
class UserProfile(models.Model):
# This field is required.
user = models.OneToOneField(User)
# Other fields here
where_heard_about_us = models.TextField()
You can then register the object as an inline object in your Django Admin

Adding a Django Action to User Admin

I'm using the Django User model for my users. What I need is to add an action on the User admin that will enable me to send a text message to the users I'll have selected.
This is how it's supposed to work:
I log into Django admin
Select the Users model
Select a user from the list of users and then select the "Send Message" action I have created.
I should be redirected to another page that will have the selected user names, and fields from a "Text Message" model that I have created to handle text messages.
So far I've had to create another model:
class UserProfile(models.Model):
user = models.OneToOneField(User) #extended the User model
phone_number = models.CharField(u'Number', max_length=20)
and then the form for the Text Messages:
class TextMessageForm(ModelForm):
class Meta:
model = TextMessage
fields = ('sender', 'to', 'message')
but I'm having trouble adding an action to the User model(raises an "model already registered error" which I solved by unregistering but then the passwords in the User model are viscible. That's why I created the UserProfile model)
So, can I be able to add an action to the User model without having to mess with how it'll display stuff on the admin?
Can I have the action redirect to the text form(or another template for that matter)?
Or is this a bad way to think of it... I'm using this API to send my texts. Any direction you can offer?
You could extend the UserAdmin admin page:
# admin.py
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.models import User
# Define a new User admin
class UserAdmin(UserAdmin):
"""My User Admin"""
# eg.
form = MyFancyForm
# or use my fancy template for the form
add_form_template = 'myadmin/user/add_form.html'
# or maybe add it to the change list
change_list_template = 'myadmin/user/change_list.html'
# Re-register UserAdmin
admin.site.unregister(User)
admin.site.register(User, UserAdmin)
https://docs.djangoproject.com/en/1.7/topics/auth/customizing/#extending-the-existing-user-model
If you just want to add a button to go to another page to send a message, I'd modify the list template to add that button.

Categories