将扩展的 Profile 模型添加到自定义用户模型 admin
Posted
技术标签:
【中文标题】将扩展的 Profile 模型添加到自定义用户模型 admin【英文标题】:Adding extended Profile model into custom user models admin 【发布时间】:2020-09-06 16:07:17 【问题描述】:如何将扩展的 Profile 模型字段(自定义用户模型字段中不可用的字段)添加到自定义用户管理 users.admin?
什么我想做的是我也想在个人信息中看到 Profile 模型字段,如 photo, date_of_birth, country, phone etc..
(见图片),我可以进行更改从这里开始。
简介模特
from django.db import models
from django.dispatch import receiver
from django.urls import reverse
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 get_absolute_url(self):
return reverse('profiles:profile-detail', kwargs='pk':self.pk)
def post_save_user_model_receiver(sender, instance, created, *args, **kwargs ):
# when a user is created(custom user model)like signup or through admin it will create those user's profile too
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)
users.admin
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)
用于在管理员中编辑用户的表单
from django import forms
from django.contrib.auth import get_user_model # or from .models import User
from django.contrib.auth.forms import ReadOnlyPasswordHashField
User = get_user_model() # this method will return the currently active user model
# or from .models import User
class UserAdminCreationForm(forms.ModelForm):
"""
A form for creating new users in admin panel. Includes all the required
fields, plus a repeated password.
"""
password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
password2 = forms.CharField(label='Confirm Password', widget=forms.PasswordInput)
class Meta:
model = User
fields = ('first_name', 'last_name', 'email')
def clean_password2(self):
# Check that the two password entries match
password1 = self.cleaned_data.get('password1')
password2 = self.cleaned_data.get('password2')
if password1 and password2 and password1 != password2:
raise forms.ValidationError("Password don't match")
return password2
def save(self, commit=True):
# Save the provided password in hashed format
user = super(UserAdminCreationForm, self).save(commit=False)
user.set_password(self.cleaned_data['password1'])
if commit:
user.save()
return user
class UserAdminChangeForm(forms.ModelForm):
"""
A form for updating users in admin panel. Includes all the fields on
the user, but replaces the password field with admin's
password hash display field.
"""
password = ReadOnlyPasswordHashField()
class Meta:
model = User
fields = ('first_name', 'last_name', 'email', 'password', 'active', 'staff', 'admin')
def clean_password(self):
# Regardless of what the user provides, return the initial value.
# This is done here, rather than on the field, because the
# field does not have access to the initial value
return self.initial['password']
【问题讨论】:
【参考方案1】:我建议您覆盖 User 模型。
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, \
PermissionsMixin
class UserManger(BaseUserManager):
"""
Add extra calling functionalities here
"""
pass
class User(AbstractBaseUser, PermissionsMixin):
"""Custom user model"""
pass
objects = UserManger()
这是基本格式。在模型中添加额外的配置文件字段
在setting.py中添加
AUTH_USER_MODEL = ' app_name . model_name '
# eg. 'core.User'
【讨论】:
我已经在使用这个用户模型了。再次阅读我要问的问题。 那么从自定义用户模型扩展配置文件模型是一个好习惯吗?以上是关于将扩展的 Profile 模型添加到自定义用户模型 admin的主要内容,如果未能解决你的问题,请参考以下文章
在 django 1.8 中将数据从原始用户模型迁移到自定义用户模型