我正在开发一个应用程序,其中我有三种不同类型的用户或角色(患者、医生和物理治疗师)
我将在这个问题中陈述的担忧来自我最初发表的这篇文章以及我从@cesar-bustios收到的说明性答案
我将简要概括一下我从上一篇文章中得到的答案,以便在我的问题中提供完整的示例并能够有更多的分析元素。
1.自定义用户模型已创建创建 Django 项目后,创建名为 userprofile 的应用程序
# settings.py
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'crispy_forms',
'userprofile',
]
# Seleccionamos que userprofile establezca el manejo de nuestros usuarios
AUTH_USER_MODEL = 'userprofile.User'
2 . 我们创建我们的用户模式(角色Patient
、、Medical
和Physiotherapist
)
# userprofile/models.py
from django.contrib.auth.models import AbstractUser
from django.db import models
# Create your models here.
# Creamos la clase User que hereda de AbstractUser para adicionar
# tres atributos booleanos `is_medical`, `is_physiotherapist`, e `is_patient`
class User(AbstractUser):
is_medical = models.BooleanField(default=False)
is_physiotherapist = models.BooleanField(default=False)
is_patient=models.BooleanField(default=False)
# Obtenemos los perfiles de cada usuario acorde a su tipo
def get_medical_profile(self):
medical_profile = None
if hasattr(self, 'medicalprofile'):
medical_profile=self.medicalprofile
return medical_profile
def get_patient_profile(self):
patient_profile = None
if hasattr(self, 'patientprofile'):
patient_profile = self.patientprofile
return patient_profile
def get_physiotherapist_profile(self):
physiotherapist_profile = None
if hasattr(self, 'physiotherapistprofile'):
physiotherapist_profile = self.physiotherapistprofile
return physiotherapist_profile
class Meta:
db_table = 'auth_user'
# Le decimos que estos campos vayan a la tabla auth_user
# de igual nombre que la de django.contrib.auth
# Creamos un modelo Profile por cada rol o tipo de usuario
# `Medical`, `Physiotherapist`, y `Patient` en donde en cada uno
# almacenaremos datos propios de cada rol de usuario
class MedicalProfile(models.Model):
user=models.OneToOneField(User, on_delete=models.CASCADE)
active = models.BooleanField(default=True)
name = models.CharField(max_length=64)
class PatientProfile(models.Model):
user=models.OneToOneField(User, on_delete=models.CASCADE)
active = models.BooleanField(default=True)
name = models.CharField(max_length=64)
class PhysiotherapistProfile(models.Model):
user=models.OneToOneField(User, on_delete=models.CASCADE)
active = models.BooleanField(default=True)
name = models.CharField(max_length=64)
我已经看到,当从类继承AbstractUser
使用创建自定义用户模型AUTH_USER_MODEL
时,当我们执行第一次迁移时,我看到我们在管理员中没有用户模块,因为我们使用 AbstractUser 对其进行了自定义,因此有必要使用用户在 Django 中处理的属性在我的 admin.py 文件中手动注册它。
归根结底,这没问题,它会记录:
3.在 Django admin 中注册 classes/models User
, PatientProfile
,MedicalProfile
和PhysiotherapistProfile
详细说明在 class 的情况下 UserAdmin
,我们继承自 admin.ModelAdmin
#userprofile/admin.py
from django.contrib import admin
from .models import User, PhysiotherapistProfile, PatientProfile, MedicalProfile
from django.contrib.auth.admin import UserAdmin
# Registramos el modelo User con los atributos por defecto que
# Django provee, además de los atributos booleanos
# 'is_medical','is_patient','is_physiotherapist'
@admin.register(User)
class UserAdmin(admin.ModelAdmin):
list_display = ('id','username','password','first_name','last_name',
'email','is_staff','is_active','is_superuser',
'is_medical','is_patient','is_physiotherapist',
'last_login','date_joined')
# Registramos los modelos para cada tipo de usuario
@admin.register(PatientProfile)
class PatientAdmin(admin.ModelAdmin):
list_display = ('id','name','active','user_id',)
@admin.register(MedicalProfile)
class MedicalAdmin(admin.ModelAdmin):
list_display = ('id','name','active','user_id',)
@admin.register(PhysiotherapistProfile)
class PhysiotherapistAdmin(admin.ModelAdmin):
list_display = ('id','name','active','user_id',)
因此,在迁移时以及通过 Web 访问管理员时,我们会详细说明我们已经拥有模型Users
、PatientProfile
、MedicalProfile
和PhysiotherapistProfile
如果我输入用户并编辑一个用户,我可以详细说明我添加了三个布尔属性is_medical
, is_patient
,is_physiotherapist
以同样的方式,当我想在管理员中创建用户时,我有这三个相同的属性可用:
但我详细说明的一件事是,当我创建用户时,密码文本字段不会加密一个人写的内容:
因此,通过这样存储它,当我们查看用户列表时,它也会以纯文本形式显示:
4. 使密码字段显示为加密
django admin 和 django 一般默认使用PBKDF2作为加密机制或函数
在这篇文章中,他们说,当我们AbstractUser
在 admin.py 文件中为它的注册创建的类中注册一个继承自 的模型时,它必须从该类继承,UserAdmin
而不是从我们用来注册的 admin.ModelAdmin来自 Django 的管理员中的模型。通过这样做,UserAdmin 使我的密码字段在输入和查看时都被加密。
我们让我们的 User
自定义模型继承自 UserAdmin
而不是 admin.ModelAdmin
#userprofile/admin.py
# Hacemos que nuestro modelo User personalizado
# herede de UserAdmin en lugar de admin.ModelAdmin
@admin.register(User)
class UserAdmin(UserAdmin):
list_display = ('id','username','password','first_name','last_name','email','is_staff','is_active','is_superuser','is_medical','is_patient','is_physiotherapist','last_login','date_joined')
进行此更改后,如果我想创建一个用户,输入密码的字段将受到保护:
以及如果我想在保存之前创建的用户后查看它:
UserAdmin
我们继承自而不是继承的事实admin.ModelAdmin
解决了问题,以便密码在 Django 管理员中被加密或“拥有”,但是,已经从 UserAdmin 继承,如果我要在 User 中创建一个新用户,这些字段不出现或我们之前添加的属性 fromis_patient
和is_physiotherapist
fromis_medical
这些属性在用户创建时不再出现,这最终是创建自定义模型并继承自AbstractUser
Es lógico, no aparecen, porque ya estoy heredando de UserAdmin
y asumo que al hacer esto, el sobreescribirá los campos que colocará en el administrador, los cuales asumo que son todos los de por defecto de Django menos los tres atributos booleanos de is_patient
, is_physiotherapist
y de is_medical
que yo he agregado antes.
Tengo esa inquietud.
¿Qué mecanismo habría para que con nuestro modelo personalizado quede el password hasheado en el admin?
o
Que cuando heredemos de UserAdmin,¿cómo podemos tambien ver reflejados los campos adicionados en el admin como is_patient
, is_physiotherapist
y de is_medical
?
A veces me pregunto si son tan necesarios estos tres campos booleanos is_patient
, is_physiotherapist
y de is_medical
o con el solo hecho de tener User
relacionado con PatientProfile
, con MedicalProfile
y con PhysiotherapistProfile
, sería suficiente para tener estos tres roles de usuario y que cada uno tenga sus propios privilegios, como lo tengo en este acercamiento
Claro esto es algo que yo debo probar.
Cualquier ayuda, consideración o aporte será altamente apreciado. Muchas gracias.
Quiero comenzar diciendo que si existiera una medalla por posts largos te la ganarías :)
Vamos, el tema con el
UserAdmin
es que está hecho exclusivamente para el usuario original de Django y usa formularios de creación y edición especiales para ese modelo. Lo que tienes que hacer entonces es heredarlos y modificarlos a tu gusto.我们的文件名可能不同,因为我在您的第一个问题中创建了项目并且正在使用同一个项目。
创建表单后,他们唯一要做的就是将原始模型更改为我们的自定义模型,我们还必须创建一个自定义模型
UserAdmin
来使用这些表单:这应该足够了。告诉我进展如何。