Extending Django User Model and Adding to Admin List Display - python

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

Related

Cannot edit user profile and change password of the custom user in django

I have a custom user model in my django project. I can create users using the form based on this model but I'm unable to edit and change the passwords. How can I make this possible?
Created the custom user models as shown below.
from django.db import models
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
class Role(models.TextChoices):
ADMIN = 'ADMIN', 'Admin'
DEVELOPER = 'DEVELOPER', 'Developer'
TESTER = 'TESTER', 'Tester'
base_role = Role.ADMIN
role = models.CharField(max_length=20, choices= Role.choices)
def save(self, *args,**kwargs):
if not self.pk:
self.role = self.base_role
return super().save(*args, **kwargs)
I tried to edit the user the profile and change password using this form.
from django.contrib.auth.forms import UserCreationForm
from .models import User
from django import forms
class RegisterUserForm(UserCreationForm):
email = forms.EmailField()
first_name = forms.CharField(max_length=50)
last_name = forms.CharField(max_length=50)
class Meta:
model = User
fields = ('username', 'first_name', 'last_name', 'email','role', 'password1', 'password2')
class EditUserForm(forms.ModelForm):
email = forms.EmailField()
first_name = forms.CharField(max_length=50)
last_name = forms.CharField(max_length=50)
class Meta:
model = User
fields = ('username', 'first_name', 'last_name', 'email')
corresponding views.py file
from django.shortcuts import render, redirect
from django.contrib.auth import authenticate, login, logout
from django.contrib import messages
from django.views.decorators.cache import never_cache
from .forms import RegisterUserForm, EditUserForm
from django.views import generic
from django.urls import reverse_lazy
from django.contrib.auth.views import PasswordChangeView
from django.contrib.auth.forms import PasswordChangeForm
from django.contrib.messages.views import SuccessMessageMixin
class EditProfileView(generic.UpdateView, SuccessMessageMixin):
form_class = EditUserForm
template_name = 'edit_profile.html'
success_url = reverse_lazy('home')
def get_object(self):
return self.request.user
def form_valid(self, form):
messages.success(self.request, 'Updated Successfully!')
return super().form_valid(form)
class PasswordsChangeView(PasswordChangeView):
form_class = PasswordChangeForm
template_name = 'change_password.html'
success_url = reverse_lazy('home')
def form_valid(self, form):
messages.success(self.request, 'Password changed successfully')
return super().form_valid(form)
The forms are working fine with the templates but it's not getting updated based on the input I've given.

django custom user field won't appear in admin form

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',
...
)}),
...
)

Django: UNIQUE constraint failed: user.username

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)

django.core.exceptions.FieldError: Unknown field(s) (number) specified for User

I am new to Django, I tried to create a new models forms but while running my server i got this error:
(The form should add a "number" to the Profile database) Thanks for helping
(The form should add a "number" to the Profile database) Thanks for helping
File "C:\Users\xxx\PycharmProjects\web_lead_app\venv\lib\site-packages\django\forms\models.py", line 266, in __new__
raise FieldError(message)
django.core.exceptions.FieldError: Unknown field(s) (number) specified for User
views.py
from .forms import UserRegisterForm, ProfileUpdateForm, UserUpdateForm
from django.contrib.auth.decorators import login_required
#login_required()
def profile(request):
u_form = UserUpdateForm()
p_form = ProfileUpdateForm()
context = {
"u_form": u_form,
"p_form": p_form
}
return render(request, "users/profile.html", context)
forms.py
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
from .models import Profile
class UserUpdateForm(forms.ModelForm):
email = forms.EmailField()
class Meta:
model = User
fields = ["email", "number"]
class ProfileUpdateForm(forms.ModelForm):
number = forms.CharField(max_length=100)
class Meta:
model = Profile
fields = ["number"]
models.py
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
number = models.CharField(max_length=100)
def __str__(self):
return f"{self.user.username} Profile"
class UserUpdateForm(forms.ModelForm):
email = forms.EmailField()
class Meta:
model = User
fields = ["email"]
Their is no number field in User model. So remove from form.

Custom fields in Custom User model not showing up while creating user in admin

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.

Categories

Resources