Django AbstractUser doesn't show model - django

I'm a django beginner and i want to add a booleanfield to AbstractUser, but it's not showing the booleanfield in the admin.
models.py
class CustomUser(AbstractUser):
selected = models.BooleanField(default=False)
USERNAME_FIELD = 'username'
REQUIRED_FIELDS = ['selected',]
def __str__(self):
return self.username
admin.py
class MyUserChangeForm(UserChangeForm):
class Meta(UserChangeForm.Meta):
model = CustomUser
class UserAdmin(BaseUserAdmin):
form = MyUserChangeForm
list_display = ('username', 'first_name', 'last_name', 'email', 'is_staff', 'selected')
admin.site.register(CustomUser, UserAdmin)
settings.py
AUTH_USER_MODEL = 'football_app.CustomUser'

in admin.py file change
class UserAdmin(BaseUserAdmin): to class UserAdmin(CustomUser):
EDIT: update your class like this
class UserAdmin(admin.ModelAdmin):
list_display = ('username', 'first_name', 'last_name', 'email', 'is_staff', 'selected')
class Meta:
model = CustomUser

You need to unregister current User admin first.
admin.site.unregister(User)
admin.site.register(CustomUser, UserAdmin)

Related

Profile model (extending custom user model) not getting registered in django admin

I am new to django and totally confused so what should i do for these..
Note- list_display = ('email', 'first_name',) 'email', 'first_name' which defined in custom user model User
I am not getting errors but it not registering the Profile model
to admin why?
if i am adding phone from Profile model to list_display = ('email', 'first_name', 'phone') i m getting error (admin.E108) The value of 'list_display[2]' refers to 'phone', which is not a callable, an attribute of 'UserAdmin', or an attribute or method on 'users.User'. How can i add phone in list_display?
I uses post_save_user_model_receiver() to auto create profile when
user is created is it best way to do it?
how can i add all Profile model fields for edit/update in users.admin (which is below).
profile model
from django.db import models
from django.dispatch import receiver
from django.db.models.signals import post_save
from django.contrib.auth import get_user_model # or from users.models import User
User = get_user_model()
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
photo = models.ImageField(null=True, blank=True)
date_of_birth = models.DateField(null=True, blank=True)
phone = models.IntegerField(null=True, blank=True)
country = models.CharField(max_length=150, null=True, blank=True)
city = models.CharField(max_length=150, null=True, blank=True)
bio = models.TextField(max_length=150, null=True, blank=True)
def __str__(self):
return str(self.user.email)
def post_save_user_model_receiver(sender, instance, created, *args, **kwargs ):
if created:
try:
Profile.objects.create(user=instance) # it create those user's profile
except:
pass
post_save.connect(post_save_user_model_receiver, sender=User)
Admin
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.auth import get_user_model
from .models import Profile
User = get_user_model()
# Define an inline admin descriptor for Employee model
# which acts a bit like a singleton
class ProfileInline(admin.StackedInline):
model = Profile
can_delete = False
verbose_name_plural = 'profile'
# Define a new User admin
class UserAdmin(BaseUserAdmin):
inlines = (ProfileInline,)
list_display = ('email', 'first_name',)
list_filter = ('admin', 'staff', 'active')
search_fields = ('email',)
ordering = ('email',)
filter_horizontal = ()
# Re-register UserAdmin
admin.site.unregister(User)
admin.site.register(User, UserAdmin)
users.admin file
from django.contrib import admin
from django.contrib.auth.models import Group
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.auth import get_user_model # or from .models import User
from .forms import UserAdminCreationForm, UserAdminChangeForm
# Register your models here.
User = get_user_model() # or from .models import User
class UserAdmin(BaseUserAdmin):
# The forms to add and change user instances
form = UserAdminChangeForm
add_form = UserAdminCreationForm
# The fields to be used in displaying the User model.
# These override the definitions on the base UserAdmin
# that reference specific fields on auth.User.
list_display = ('email', 'first_name', 'get_phone', 'last_login', 'date_joined', 'is_admin')
list_filter = ('admin', 'staff', 'active')
list_select_related = ('profile',)
def get_phone(self, instance): # to show the Phone in list display from the Profile Model
return instance.profile.phone
get_phone.short_description = 'Phone'
fieldsets = (
(None, {'fields': ('email', 'password')}),
('Personal Info', {'fields': ('first_name', 'last_name',)}),
('Permissions', {'fields': ('admin', 'staff', 'active')}),
)
# 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': ('email', 'first_name', 'last_name', 'password1', 'password2', )
}
),
)
search_fields = ('email',)
ordering = ('email',)
filter_horizontal = ()
admin.site.register(User, UserAdmin)
# Remove Group Model from admin. We're not using it.
admin.site.unregister(Group)

Display custom form in Django admin

I created a custom user model with country in it:
models.py
class CustomUser(AbstractUser):
country = models.CharField(max_length=50, default="None")
Then added custom forms with form field country which is a ChoiceField and shows all the countries:
forms.py
class CustomUserCreationForm(UserCreationForm):
country = forms.ChoiceField(choices=sorted(COUNTRIES.items()), label="Country")
class Meta(UserCreationForm):
model = CustomUser
fields = '__all__'
class CustomUserChangeForm(UserChangeForm):
country = forms.ChoiceField(choices=sorted(COUNTRIES.items()), label="Country")
class Meta(UserChangeForm):
model = CustomUser
fields = '__all__'
Then I registered it in the admin with:
admin.py
class CustomUserAdmin(UserAdmin):
add_form = CustomUserCreationForm
form = CustomUserChangeForm
model = CustomUser
list_display = ['email', 'username', 'is_staff',]
admin.site.register(CustomUser, CustomUserAdmin)
It registered and everything is working fine, I am able to save the model with Django shell and programmatically, but I am not able to display it in the admin console. When I try to try to create a new user from the admin, I just see three fields - username, password and password confirmation.
Do I have to extend the admin template for this new field to show up?
To do this you will have to add_fieldsets under CustomUserAdmin in admin.py:
class CustomUserAdmin(UserAdmin):
add_form = CustomUserCreationForm
form = CustomUserChangeForm
model = CustomUser
list_display = ['email', 'username', 'is_staff',]
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('username', 'password1', 'password2', 'country'),
}),
)
admin.site.register(CustomUser, CustomUserAdmin)
In Django 4.1+, the add_form option on a ModelAdmin has been removed. You should instead use the get_form() argument, like follows:
···python
class CustomUserAdmin(UserAdmin):
add_form = CustomUserCreationForm
form = CustomUserChangeForm
def get_form(self, request, obj=None, change=False, **kwargs):
if not change and not obj:
self.form = self.add_form
return super().get_form(request, obj, **kwargs)
···

Extending default user using Abstract User

I am trying to add some extra fields in default user model. But the new fields is not showing up in admin page. Here are the models of 'users' app.
models.py
from django.db import models
from django.contrib.auth.models import AbstractUser
class CustomUser(AbstractUser):
q1 = models.TextField()
q2 = models.TextField()
forms.py
from django import forms
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
from .models import CustomUser
class CustomUserCreation(UserCreationForm):
class Meta(UserCreationForm.Meta):
model = CustomUser
fields = ('username', 'email', 'q1', 'q2')
class CustomUserChange(UserChangeForm):
class Meta:
model = CustomUser
fields = ('username', 'email', 'q1', 'q2')
admin.py
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from .forms import CustomUserCreation, CustomUserChange
from .models import CustomUser
class CustomUserAdmin(UserAdmin):
add_form = CustomUserCreation
form = CustomUserChange
list_display = ['email', 'username', 'password', 'q1', 'q2']
model = CustomUser
admin.site.register(CustomUser, CustomUserAdmin)
P.S. I have added AUTH_USER_MODEL = users.CustomUser in settings.py
In your admin.py file you need to override UserAdmin as:
class CustomUserAdmin(BaseUserAdmin):
form = CustomUserChange
add_form = CustomUserCreation
list_display = ('email', 'username', 'password', 'q1', 'q2')
fields = ('email', 'username', 'password', 'q1', 'q2')
model = CustomUser
admin.site.register(CustomUser, UserAdmin)
Check this example in the docs for more understanding link
Please check the following things into your django project.
Have you added AUTH_USER_MODEL = 'users.models.CustomUser' to your settings.py file ?
Ensure you have added q1 and q2 to your fields attribute in CustomUserAdmin as follow:
class CustomUserAdmin(UserAdmin):
add_form = CustomUserCreation
form = CustomUserChange
list_display = ['email', 'username', 'password', 'q1', 'q2']
fields = ['email', 'username', 'password', 'q1', 'q2']
model = CustomUser
You can just create a user profile model with a OneToOne relation and fire it up using signal whenever a user has been added without having to touch the User model.
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.contrib.auth.models import User
class Profile(models.Model):
user=models.OneToOneField(User, on_delete=models.CASCADE)
q1 = models.TextField()
q2 = models.TextField()
def __unicode__(self):
return self.user.q1
def create_profile(sender, **kwargs):
user = kwargs["instance"]
if kwargs["created"]:
user_profile = Profile(user=user)
user_profile.save()
post_save.connect(create_profile, sender=User)

Django UpdateView disable some fields

I have made a class view inheriting UpdateView. I have specified the fields and models from which the forms should be built. Now say if i have a field email, then I want to disable it in the form. I have no clues as to how it can be done.
class UserUpdate(UpdateView):
model = Users
fields = ['email', 'first_name', 'last_name', 'birth_date']
template_name = 'users_update_form.html'
success_url = '/index/'
To hide it:
class UserUpdate(UpdateView):
model = Users
fields = ['first_name', 'last_name', 'birth_date']
template_name = 'users_update_form.html'
In this case there is no need to create a separate Form class - as this is handled by the UpdateView.
To make the fiel readonly:
class UserForm(forms.ModelForm):
class Meta:
model = Users
fields = ['email', 'first_name', 'last_name', 'birth_date']
email = forms.CharField(widget=forms.TextInput(attrs={'readonly':'readonly'}))
def clean_email(self):
return self.initial['email']
class UserUpdate(UpdateView):
model = Users
form_class = UserForm
Note for Django 1.9
Django 1.9 has a disabled option built in. Using this allows you to skip the additional clean method.
class UserForm(forms.ModelForm):
class Meta:
model = Users
fields = ['email', 'first_name', 'last_name', 'birth_date']
email = forms.CharField(disabled=True)
Define a UserForm with exclude fields which you don't want to show in the form
class UserForm(forms.ModelForm):
class Meta:
model = Users
exclude = ('email',) # add fields to disable it in the form
If you want to make field readonly in > django 1.9
use disabled
class UserForm(forms.ModelForm):
email = forms.CharField(disabled=True)
class Meta:
model = Users
fields = ['email', 'first_name', 'last_name', 'birth_date']
Then specify form in view.
class UserUpdate(UpdateView):
model = Users
form_class = UserForm
....

Manually register the change password feature in Django Admin

I wrote a custom admin class for Users in the Django Admin as follows:
class UserAdmin(admin.ModelAdmin):
model = User
list_display = ['email', 'first_name', 'last_name', 'last_login', 'date_joined', 'is_superuser', 'is_active']
list_filter = ['is_active', 'groups']
search_fields = ['email', 'first_name', 'last_name']
admin.site.unregister(User)
admin.site.register(User, UserAdmin)
This breaks the 'change password' feature in the Django Admin. What do I have to add to my custom class to allow it to work again?
Thanks.
You need to inherit from django.contrib.auth.admin.UserAdmin, rather than
admin.ModelAdmin