将扩展的 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)

在 Django 中使用自定义字段扩展用户模型

在 django 1.8 中将数据从原始用户模型迁移到自定义用户模型

将 TableView 中的 CheckBox 选中状态绑定到自定义模型属性

如何将存储过程结果映射到自定义类?

将 Django auth UserAdmin 用于自定义用户模型