I created a custom user model in django with an additional field.
However although I can see it appear in the list view in Django's admin it won't appear in the form to create or update a user, even though I've amended these.
models.py
from django.contrib.auth.models import AbstractUser
from django.db import models
class CustomUser(AbstractUser):
# Need to support codes with leading 0, hence CharField
secret = models.CharField(max_length=5)
def __str__(self):
return self.username
forms.py
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
from .models import CustomUser
class CustomUserCreationForm(UserCreationForm):
class Meta:
model = CustomUser
fields = ('username', 'email', 'secret')
class CustomUserChangeForm(UserChangeForm):
class Meta:
model = CustomUser
fields = ('username', 'email', 'secret')
admin.py
from django.contrib import admin
from django.contrib.auth import get_user_model
from django.contrib.auth.admin import UserAdmin
from .forms import CustomUserCreationForm, CustomUserChangeForm
from .models import CustomUser
class CustomUserAdmin(UserAdmin):
add_form = CustomUserCreationForm
form = CustomUserChangeForm
model = CustomUser
list_display = ['email', 'username', 'secret']
admin.site.register(CustomUser, CustomUserAdmin)
Have you tried editing the fieldsets parameter in the CustomUserAdmin class?
admin.py:
from django.contrib.auth.admin import UserAdmin
class CustomUserAdmin(UserAdmin, ...)
fieldsets = (
(('User Details'), {'fields': (
'first_name',
'last_name',
'password',
)}),
(('Section Title'), {'fields': (
'field1',
'field2',
...
)}),
...
)
Related
I am trying to display the password in the Admin backend table in the following way, containing the algorithm, iterations, salt and hash:
However, my current page looks like the following:
As you can see it is just the hashed password, not displaying any of the information unlike the above. Can anyone see where I am going wrong?
Please find my code below:
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from hobbies.models import extendedUser, User, Hobby
from .forms import LoginForm, SignUpForm
from django.forms import ModelForm
from django.contrib.auth.forms import ReadOnlyPasswordHashField
#admin.site.register(User,UserAdmin)
class CustomUserAdmin(UserAdmin):
add_form = SignUpForm
form = LoginForm
model = extendedUser
readonly_fields = ["password"]
list_display = ('email', 'is_staff', 'is_active',)
list_filter = ('email', 'is_staff', 'is_active',)
fieldsets = (
(None, {'fields': ('email', 'password', 'city')}),
('Permissions', {'fields': ('is_staff', 'is_active')}),
)
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('email', 'password', 'is_staff', 'is_active')}
),
)
search_fields = ('email',)
ordering = ('email',)
admin.site.register(User, CustomUserAdmin)
Thank you for your time,
Alex
I think they use display using this function:
get_session_auth_hash() which is a part of the base abstract user in django.contrib.auth.base_user
I have a problem using Djangos Default user from django.contrib.auth.models but trying to use it with my custom User model, using from django.contrib.auth.models import AbstractUser.
So here is my User model:
from django.db import models
from django.contrib.auth.models import AbstractUser, UserManager as AbstractUserManager
# from django.conf import settings
from django_countries.fields import CountryField
# https://github.com/SmileyChris/django-countries
from django.db.models.signals import post_save
from django.dispatch import receiver
class UserManager(AbstractUserManager):
pass
class User(AbstractUser):
"""auth/login-related fields"""
is_a = models.BooleanField('a status', default=False)
is_o = models.BooleanField('o status', default=False)
def __str__(self):
return "{} {}".format(self.first_name, self.last_name)
#receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
if created:
User.objects.set_password(instance.password)
and here is my Profile model:
from django.db import models
from django_countries.fields import CountryField # https://github.com/SmileyChris/django-countries
from django.contrib.auth import get_user_model
User = get_user_model()
# https://medium.com/swlh/best-practices-for-starting-a-django-project-with-the-right-user-model-290a09452b88
from django.db.models.signals import post_save
from django.dispatch import receiver
class Profile(models.Model):
"""non-auth-related/cosmetic fields"""
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='Profile')
birth_date = models.DateTimeField(auto_now=False, auto_now_add=False, null=True)
nationality = CountryField(null=True)
GENDER_CHOICES = (
('M', 'Male'),
('F', 'Female'),
)
gender = models.CharField(max_length=1, choices=GENDER_CHOICES, null=True)
def __str__(self):
return f'{self.user.username} Profile'
"""receivers to add a Profile for newly created users"""
#receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
#receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
instance.profile.save()
But before adding User.objects.set_password(instance.password) to my User model, I did it in py shell, which worked perfectly.
But now I added this line in my User model, and when I'm using Postman to post a User:
{
"username":"1564",
"password":"12345678",
"first_name":"Al",
"last_name":"Pongvf",
"email":"ahgj#live.fr"
}
It gives me this error message:
IntegrityError at /user/create/
UNIQUE constraint failed: ep_user.username
Which I don't get it because I'm creating a new user with a total new username.
I've searched for a solution, but I didn't get lucky:
StackOverflow
1
StackOverflow
2
StackOverflow
3
StackOverflow
4
Does anyone know what am I missing? or doing wrong?
Thanks!
UPDATE:
Here is my User Serializer:
from rest_framework import serializers
from django.contrib.auth import get_user_model
from ..models.model_user import *
# from .serializers_profile import *
class UserIndexSerializer(serializers.ModelSerializer):
# profile = ProfileIndexSerializer()
class Meta:
model = User
fields = [
'id',
'username',
'password',
'first_name',
'last_name',
'email',
'is_a',
'is_o'
# 'profile'
]
class UserCreateSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = [
'username',
'password',
'first_name',
'last_name',
'email',
'is_a',
'is_o'
]
class UserDetailsSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = '__all__'
And here is my User View:
from rest_framework import generics
from django.contrib.auth import get_user_model
from ..models.model_user import *
from ..serializers.serializers_user import *
class UserIndex(generics.ListAPIView):
"""List all users, or create a new user."""
queryset = User.objects.all().order_by('id')
serializer_class = UserIndexSerializer
class UserCreate(generics.CreateAPIView):
"""List all art pieces, or create a new art piece."""
queryset = User.objects.all()
serializer_class = UserCreateSerializer
class UserDetails(generics.RetrieveUpdateDestroyAPIView):
"""Retrieve, update or delete a user instance."""
queryset = User.objects.all()
serializer_class = UserDetailsSerializer
And my admin.py:
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
# Register your models here.
from .models.model_user import *
from .models.model_profile import *
admin.site.register(User, UserAdmin)
admin.site.register(Profile)
I am using built-in Django Admin, I have two types of users, need to call both using different urls i.e http://127.0.0.1:8000/admin/staff & http://127.0.0.1:8000/admin/customer need to break-down user model into two separate models Staff & Customer. Staff model will be used for Admin users & Customer model will be used for front-end users.
Note: I have kept db table names same as default auth_user, auth_group ...etc
I have created app named users in project
So far I have tried following things:
models.py
from django.contrib.auth.models import (
AbstractUser, Permission, Group, GroupManager)
from django.db import models
from django.utils.translation import gettext_lazy as _
class Staff(AbstractUser):
class Meta(AbstractUser.Meta):
swappable = 'AUTH_USER_MODEL'
verbose_name = _('staff')
verbose_name_plural = _('staffs')
db_table = 'auth_user'
class Customer(AbstractUser):
class Meta(AbstractUser.Meta):
swappable = 'AUTH_USER_MODEL'
verbose_name = _('customer')
verbose_name_plural = _('customers')
db_table = 'auth_user'
admin.py
from django.contrib import admin
from django.contrib.auth.models import Group, User, Permission
from django.contrib.auth.admin import GroupAdmin, UserAdmin
from django.utils.translation import ugettext_lazy as _
from django import forms
from django.forms import ModelForm, Select
from users.models import Staff, Customer
class MyGroupAdminForm(forms.ModelForm):
class Meta:
model = Group
fields = ('name', 'permissions')
permissions = forms.ModelMultipleChoiceField(
Permission.objects.exclude(content_type__app_label__in=[
'auth', 'admin', 'sessions', 'users', 'contenttypes']),
widget=admin.widgets.FilteredSelectMultiple(_('permissions'), False))
class MyUserAdminForm(forms.ModelForm):
model = User
groups = forms.ModelChoiceField(Group.objects, label='Role')
class Meta:
model = User
fields = '__all__'
class CustomUserAdmin(UserAdmin):
form = MyUserAdminForm
fieldsets = (
(None, {'fields': ('username', 'password')}),
(_('Personal info'), {'fields': ('first_name', 'last_name', 'email')}),
(_('Permissions'), {'fields': ('is_active', 'is_staff', 'is_superuser',
'groups',)}),
(_('Important dates'), {'fields': ('last_login', 'date_joined')}),
)
class CustomGroupAdmin(GroupAdmin):
form = MyGroupAdminForm
# admin.site.unregister(User)
admin.site.unregister(Group)
# admin.site.register(User, CustomUserAdmin)
# admin.site.register(Group, CustomGroupAdmin)
admin.site.register(Staff, CustomUserAdmin)
admin.site.register(Group, CustomGroupAdmin)
settings.py
AUTH_USER_MODEL = "users.Staff"
Now when I am trying to change any staff user I am getting following error:
OperationalError at /admin/users/staff/1/change/
(1054, "Unknown column 'auth_user_groups.staff_id' in 'where clause'")
Request Method: GET
Request URL: http://127.0.0.1:8000/admin/users/staff/1/change/
Django Version: 2.2.8
Exception Type: OperationalError
Exception Value:
(1054, "Unknown column 'auth_user_groups.staff_id' in 'where clause'")
Exception Location: C:\Users\kalim.ullah\Envs\Cert\lib\site-packages\MySQLdb\connections.py in query, line 239
Python Executable: C:\Users\kalim.ullah\Envs\Cert\Scripts\python.exe
Python Version: 3.8.0
Python Path:
['D:\\projects\\certdashboard',
'C:\\Users\\kalim.ullah\\Envs\\Cert\\Scripts\\python38.zip',
'C:\\Users\\kalim.ullah\\Envs\\Cert\\DLLs',
'C:\\Users\\kalim.ullah\\Envs\\Cert\\lib',
'C:\\Users\\kalim.ullah\\Envs\\Cert\\Scripts',
'c:\\users\\kalim.ullah\\appdata\\local\\programs\\python\\python38\\Lib',
'c:\\users\\kalim.ullah\\appdata\\local\\programs\\python\\python38\\DLLs',
'C:\\Users\\kalim.ullah\\Envs\\Cert',
'C:\\Users\\kalim.ullah\\Envs\\Cert\\lib\\site-packages']
Server time: Fri, 10 Jan 2020 13:00:41 +0000
Please guide me the proper way of doing this
Thanks
I am using a custom user model with an extra field 'uid'. While i am trying to create a new user from the admin page, the uid field is not showing up. I've created a custom user create and update form.please see the code below.
models.py
from django.db import models
# Create your models here.
from django.contrib.auth.models import AbstractUser
class CustomUser(AbstractUser):
uid = models.CharField(max_length=50)
forms.py
from django import forms
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
from .models import CustomUser
class CustomUserCreationForm(UserCreationForm):
uid = forms.CharField(label = "uid")
class Meta(UserCreationForm):
model = CustomUser
fields = ('username', 'password', 'uid')
def save(self, commit=True):
user = super(UserCreateForm, self).save(commit=False)
user.uid = self.cleaned_data["uid"]
if commit:
user.save()
return user
Did i miss something or am i doing it wrong? please help.
Edit:
admin.py
from django.contrib import admin
from support.models import CustomUser
# Register your models here.
from django.contrib.auth import get_user_model
from django.contrib.auth.admin import UserAdmin
from .forms import CustomUserCreationForm, CustomUserChangeForm
class CustomUserAdmin(UserAdmin):
add_form = CustomUserCreationForm
form = CustomUserChangeForm
model = CustomUser
list_display = ['username','password','uid']
admin.site.register(CustomUser, CustomUserAdmin)
Don't know if it's the right way, changing the CustomUserAdmin as shown in this answer https://stackoverflow.com/a/45701173/9740712 made the extra field appear.
I am trying to extend my user model with a profile and then add the new profile fields to the user list display so that it is searchable. Everything is working up until adding it to the admin list display.
I keep getting this error 'User' object has no attribute 'MyProfile'
models.py
from django.db import models
# Create your models here.
from django.contrib.auth.models import User
from django.utils.translation import ugettext as _
from userena.models import UserenaBaseProfile
class MyProfile(UserenaBaseProfile):
user = models.OneToOneField(User,
unique=True,
verbose_name=_('user'),
related_name='my_profile')
dealer_num = models.CharField(blank=True,
max_length=15,
verbose_name="Dealer Number")
Admin.py
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.models import User
from .models import MyProfile
class ProfileInline(admin.StackedInline):
model = MyProfile
can_delete = False
verbose_name_plural = 'Profile'
fk_name = 'user'
fields = ('user', 'dealer_num')
class UserAdmin(UserAdmin):
inlines = (ProfileInline, )
list_display = ('username', 'get_dealer_num')
def get_inline_instances(self, request, obj=None):
if not obj:
return list()
return super(UserAdmin, self).get_inline_instances(request, obj)
def get_dealer_num(self, obj):
return obj.MyProfile.dealer_num
admin.site.unregister(User)
admin.site.register(User, UserAdmin)
Try this:
def get_dealer_num(self, obj):
return MyProfile.objects.get(user=obj).dealer_num