将扩展的 Profile 模型添加到自定义用户模型 admin

问题描述

如何将扩展的 Profile 模型字段(自定义用户模型字段中不可用的字段)添加到自定义用户管理 users.admin?

How can i add extended Profile model fields (fields which are not available in custom user model fields) into custom users admin users.admin?

什么我想做的是我也想看到 Profile 模型字段,如 photo、date_of_birth、country、phone 等.在个人信息中(见图)&我可以从这里对其进行更改.
个人资料模型

what i am trying to do is that i want too see Profile model fields like photo, date_of_birth, country, phone etc.. inside the Personal Info(see in image) & i can make changes in it from here.
profile model

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']


解决方案

我建议你重写 User 模型.

I would recommend that you override the User model.

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()

这是基本格式.在模型中添加额外的配置文件字段

This is the basic format. Add the extra profile fields in the model

在setting.py中添加

in setting.py add

AUTH_USER_MODEL = '{{ app_name }}.{{ model_name }}'
# eg. 'core.User'

相关文章