Django 上的用户角色架构
User roles schema on Django
一个很棒的问候社区
我的问题与 Django 中管理用户和模式用户的类型有关,首先我向您道歉,以防我的问题太过 "newbies" 或没有意义,我是开始将我与 Django 用户模式及其在项目中的不同工作可能性联系起来。
我有以下情况。
我正在构建一个应用程序,我将在其中拥有三种不同的用户类型:
- 医疗
- 患者
- 物理治疗师
我正在使用默认的 Django 身份验证方案 (django.contrib.auth)。
最初,我确实认为在这种实体方案中,用户 table 是 auth_user
table 在 Django 中保存用户创建的位置:
我有 is_patient
、is_medical
和 is_physiotherapist
字段,例如用户 table 中的布尔属性。
像一个特定的细节,我了解到在 Django 默认模型中,用户不可能修改或添加属性或字段。
这是我无法在用户 table.
中添加 is_patient
、is_medical
和 is_physiotherapist
布尔字段的一个重要而有力的原因
一个经典的建议是使用 Userprofile table 扩展 User 模型,在其中我通过 OneToOne 关系向 User 模型添加字段或属性。基本示例如下:
通过这种方式,我可以让我在 Django 中的用户拥有现场照片并在给定时刻上传一张...
趁着前面的优势,
以下模式适合或可以替代管理用户角色(patient
、medical
和 physiotherapist
用户类型)?
我将有以下关系:
用户医疗和用户患者
用户理疗师和用户患者
他们和其他 table 之间等等...
采用这种方法,这些关系不会受到影响吗?
Users 和 UserProfile 之间将保存不同的用户 table。
从可扩展性的角度来看,这是一个好的做法吗?我的 table 可能崩溃或我的数据库?
此外,我还看到了其他替代方案,例如:
- 角色Table/Model
我将有一个 table/model 独立或独立的角色,这可以与 Django 用户模型相关(例如,一个用户可以有多个角色)
当我想在 specia 中存储有关某个角色的独有信息时,这种方法很有用?
我忽略或不知道让我工作的粒度等级。我已经看到权限和授权系统让我以一种方式进行创建、编辑和删除操作....
在这里,我可以看到创建的群组吗?
例如医疗组并为他们分配权限并将此权限链接到组成该组的用户?这是另一个好的选择吗?
这个选项看起来比较单一,虽然我不知道用户是否可以根据具有的组权限进行一些操作......我不知道这个想法是否correct/right
- AUTH_USER_MODEL Creating a Custom User model
我对患者、医疗和物理治疗师用户的要求,需要构建自定义用户模型吗?
您可以创建或不创建自定义用户模型,在任何情况下,您都可以拥有三个单独的模型来存储相关数据,具体取决于用户是患者、医生、物理治疗师还是这些的任意组合。
如果您的权限方案仅由角色(患者、医生、物理治疗师)决定,那么您不需要使用 Django 的权限系统,因为您知道任何用户的角色,并且您可以,最坏的情况,硬编码授权规则。
在这种情况下,特别是如果您想为患者、医生和物理治疗师存储不同的信息,您可以为每个人创建一个模型,并为每个人的用户模型创建一个 OneToOne 字段。
class Medic(models.Model):
user = models.OneToOneField(User, primary_key=True)
# other fields
class Physio(models.Model):
user = models.OneToOneField(User, primary_key=True)
# other fields
class Patient(models.Model):
user = models.OneToOneField(User, primary_key=True)
# other fields
通过这种方式,您可以在您的应用程序逻辑中为每种类型的用户隐式地提供不同的 permissions/roles(并且如果您在特殊情况下需要它们,仍然可以使用 Django 提供的组和权限,例如 ChiefMedical... ).
您必须为您的应用程序逻辑定义一些方法,例如
def user_is_patient(user):
...
如果您遵循此路径,最好进行良好的测试以确保您不会遇到意外情况,例如用户是 Medic 和 Physio...
Django 还允许您对用户模型进行子类化。在幕后它会做与上面代码相同的事情,所以最好像上面所示那样明确地做它(这样你访问那个对象中不存在的属性的可能性就会降低!)
Taking advantage of the previous, The following schema can be suited or can be an alternative for manage user roles (patient, medical and physiotherapist user types) ?
您显示的架构不是很好,因为它让您将所有用户类型的信息存储在相同的 table(并且具有相同的字段)中。例如,Medics 和 Physios 将有一个血型字段类型,如 Patients,它可能不会被定义。
The different users will be saved between the Users and UserProfile table. Is this a good practice in the scalability sense? My tables could be crash or my database?
此解决方案应该没有可伸缩性问题(只要您没有每天写入数百万个新条目)并且您始终可以在进一步优化数据库。但是,您必须确保您的应用不接受 'forbidden' 条目(例如没有 Medic、Physio 或 Patient 资料的用户)
Here, can I see the groups creation? For example a medical group and allocate them permissions and linked this permissions to the users that compose the group ? Is this another good alternative? This option seem more single although I don't know if an user could make some operations according to the group privileges that have ... I don't know if this thinking is correct/right
您可以(应该)使用 Django 的权限系统来为您的用户授予权限。您可以使用它们为同一类型的用户授予不同的权限(例如,拥有比其他人更多权限的医生......或者拥有首席理疗师组......)
Django 允许您为组分配权限。
但我不认为组可以替换每个用户的自定义模型,因为您想为他们存储信息。拥有自定义模型和组将是多余的,并且会使您的应用程序更难维护。
My requirements for patient, medical and physiotherapist users, require build a custom user model?
这个选项不是很好(除非它是您唯一的选择),因为您的应用程序将无法重复使用,并且您可能还会遇到某些软件包的问题。
我看了一眼问题的评论,我看到了一些问题:
()
我意识到你的用户模型与原始数据模型不匹配,因为在用户模型中有 get_medical_profile
、get_patient_profile
和 get_physiotherapist_profile
函数,你假设任何用户可以同时拥有多个个人资料,这既不会反映在您使用 OneToOneField 的个人资料模型(医疗、患者和物理治疗师)中,也不会反映在问题的原始数据模型中,这是关于抽象的重要事情 class -责任。要求(根据下面的模型)似乎是 "one user can have only one profile".
所以..我认为这可以通过一种简单明了的方式解决,您不需要参与整体身份验证 esquema,如组和权限或向用户模型添加其他属性:
class UserProfile(models.Model):
user = models.OneToOneField(User)
# common fields shared by medical, patient and physiotherapist profiles
class MedicalUser(models.Model):
profile = models.OneToOneField(UserProfile)
# medical fields here
class PatientUser(models.Model):
profile = models.OneToOneField(UserProfile)
# patient fields here
class PhysiotherapistUser(models.Model):
profile = models.ForeignKey(UserProfile)
# patient fields here
如您所见,您可以拥有一个配置文件,其中包含所有配置文件共享的公共字段。每个配置文件都有一个特定的模型。
此外,您可以通过下面这个小功能检查用户是否医疗,如果没有与个人资料关联的医疗资料,那么它会引发异常,这意味着它是一个未指定的个人资料:
def is_medical_profile(profile):
try:
profile.medical_user
return True
except:
return False
您也可以通过这种方式在您的模板中使用它(作为自定义模板标签):
{% if profile | is_medical_profile %}
使用这种方法你不需要设置AUTH_USER_MODEL
我希望这会改进您的解决方案。
补充说明:
以防万一您决定拥有自定义用户模型,设置 settings.AUTH_USER_MODEL 并将其用于用户的外键。
在很棒的书的一段文字上 Two scoops of Django 说:
From Django 1.5 onwards, the official preferred way to attach
ForeignKey, OneToOneField, or ManyToManyField to User
因此,您的用户配置文件模型将更改如下:
from django.conf import settings
from django.db import models
class UserProfile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL)
是的,它看起来有点奇怪,但这是 Django 官方文档的建议。
@geoom @Ire @lorenzo-peña 我通过 Django 管理站点创建了一个用户,并通过 [=] 检查了他们的属性(is_medical、is_patient、is_physiotherapist) 27=]shell
In [6]: User.objects.filter(username='agarcial').values('is_medical','is_patient','is_physiotherapist')
Out[6]: [{'is_physiotherapist': True, 'is_patient': True, 'is_medical': True}]
目前,在我的 views.py 中,只有当用户属于三种用户类型(医疗、患者或物理治疗师)之一时,我才会登录
# Create your views here.
class ProfileView(LoginRequiredMixin, TemplateView):
template_name = 'profile.html'
def get_context_data(self, **kwargs):
self.request.session['Hi'] = True
context = super(ProfileView, self).get_context_data(**kwargs)
is_auth = False
name = None
# Check if in the request goes the user
user = self.request.user
# Check about of possible cases (For now is one profile)
if user.is_medical:
#if self.request.user.is_authenticated():
print (user.is_medical)
is_auth = True
profile=user.get_medical_profile()
#name = self.request.user.username
data = {
'is_auth':is_auth,
'profile':profile,
}
context.update({'userprofile':profile, 'data':data})
elif user.is_patient:
print (user.is_patient)
is_auth=True
profile=user.get_patient_profile()
data = {
'is_auth':is_auth,
'profile':profile,
}
context.update({'userprofile':profile,'data':data})
elif user.is_physiotherapist:
print (user.is_physiotherapist)
is_auth=True
profile=user.get_physiotherapist_profile()
data = {
'is_auth':is_auth,
'profile':profile,
}
context.update({'userprofile':profile,'data':data})
return context
def get_userprofile(self):
return self.request.user.userprofile
如果我检查其他可能的组合(用户患者、医生和物理治疗师)这可行吗?
我想为(医生、患者、物理治疗师)创建组并为授权主题绑定用户,尽管我应该审查授权过程的其他事情,例如 django guardian?
这个怎么样?
一个很棒的问候社区
我的问题与 Django 中管理用户和模式用户的类型有关,首先我向您道歉,以防我的问题太过 "newbies" 或没有意义,我是开始将我与 Django 用户模式及其在项目中的不同工作可能性联系起来。
我有以下情况。
我正在构建一个应用程序,我将在其中拥有三种不同的用户类型:
- 医疗
- 患者
- 物理治疗师
我正在使用默认的 Django 身份验证方案 (django.contrib.auth)。
最初,我确实认为在这种实体方案中,用户 table 是 auth_user
table 在 Django 中保存用户创建的位置:
我有 is_patient
、is_medical
和 is_physiotherapist
字段,例如用户 table 中的布尔属性。
像一个特定的细节,我了解到在 Django 默认模型中,用户不可能修改或添加属性或字段。
这是我无法在用户 table.
中添加is_patient
、is_medical
和 is_physiotherapist
布尔字段的一个重要而有力的原因
一个经典的建议是使用 Userprofile table 扩展 User 模型,在其中我通过 OneToOne 关系向 User 模型添加字段或属性。基本示例如下:
通过这种方式,我可以让我在 Django 中的用户拥有现场照片并在给定时刻上传一张...
趁着前面的优势,
以下模式适合或可以替代管理用户角色(patient
、medical
和 physiotherapist
用户类型)?
我将有以下关系:
用户医疗和用户患者
用户理疗师和用户患者
他们和其他 table 之间等等...
采用这种方法,这些关系不会受到影响吗?
Users 和 UserProfile 之间将保存不同的用户 table。 从可扩展性的角度来看,这是一个好的做法吗?我的 table 可能崩溃或我的数据库?
此外,我还看到了其他替代方案,例如:
- 角色Table/Model
我将有一个 table/model 独立或独立的角色,这可以与 Django 用户模型相关(例如,一个用户可以有多个角色) 当我想在 specia 中存储有关某个角色的独有信息时,这种方法很有用?
我忽略或不知道让我工作的粒度等级。我已经看到权限和授权系统让我以一种方式进行创建、编辑和删除操作....
在这里,我可以看到创建的群组吗? 例如医疗组并为他们分配权限并将此权限链接到组成该组的用户?这是另一个好的选择吗? 这个选项看起来比较单一,虽然我不知道用户是否可以根据具有的组权限进行一些操作......我不知道这个想法是否correct/right
- AUTH_USER_MODEL Creating a Custom User model
我对患者、医疗和物理治疗师用户的要求,需要构建自定义用户模型吗?
您可以创建或不创建自定义用户模型,在任何情况下,您都可以拥有三个单独的模型来存储相关数据,具体取决于用户是患者、医生、物理治疗师还是这些的任意组合。
如果您的权限方案仅由角色(患者、医生、物理治疗师)决定,那么您不需要使用 Django 的权限系统,因为您知道任何用户的角色,并且您可以,最坏的情况,硬编码授权规则。
在这种情况下,特别是如果您想为患者、医生和物理治疗师存储不同的信息,您可以为每个人创建一个模型,并为每个人的用户模型创建一个 OneToOne 字段。
class Medic(models.Model):
user = models.OneToOneField(User, primary_key=True)
# other fields
class Physio(models.Model):
user = models.OneToOneField(User, primary_key=True)
# other fields
class Patient(models.Model):
user = models.OneToOneField(User, primary_key=True)
# other fields
通过这种方式,您可以在您的应用程序逻辑中为每种类型的用户隐式地提供不同的 permissions/roles(并且如果您在特殊情况下需要它们,仍然可以使用 Django 提供的组和权限,例如 ChiefMedical... ).
您必须为您的应用程序逻辑定义一些方法,例如
def user_is_patient(user):
...
如果您遵循此路径,最好进行良好的测试以确保您不会遇到意外情况,例如用户是 Medic 和 Physio...
Django 还允许您对用户模型进行子类化。在幕后它会做与上面代码相同的事情,所以最好像上面所示那样明确地做它(这样你访问那个对象中不存在的属性的可能性就会降低!)
Taking advantage of the previous, The following schema can be suited or can be an alternative for manage user roles (patient, medical and physiotherapist user types) ?
您显示的架构不是很好,因为它让您将所有用户类型的信息存储在相同的 table(并且具有相同的字段)中。例如,Medics 和 Physios 将有一个血型字段类型,如 Patients,它可能不会被定义。
The different users will be saved between the Users and UserProfile table. Is this a good practice in the scalability sense? My tables could be crash or my database?
此解决方案应该没有可伸缩性问题(只要您没有每天写入数百万个新条目)并且您始终可以在进一步优化数据库。但是,您必须确保您的应用不接受 'forbidden' 条目(例如没有 Medic、Physio 或 Patient 资料的用户)
Here, can I see the groups creation? For example a medical group and allocate them permissions and linked this permissions to the users that compose the group ? Is this another good alternative? This option seem more single although I don't know if an user could make some operations according to the group privileges that have ... I don't know if this thinking is correct/right
您可以(应该)使用 Django 的权限系统来为您的用户授予权限。您可以使用它们为同一类型的用户授予不同的权限(例如,拥有比其他人更多权限的医生......或者拥有首席理疗师组......)
Django 允许您为组分配权限。
但我不认为组可以替换每个用户的自定义模型,因为您想为他们存储信息。拥有自定义模型和组将是多余的,并且会使您的应用程序更难维护。
My requirements for patient, medical and physiotherapist users, require build a custom user model?
这个选项不是很好(除非它是您唯一的选择),因为您的应用程序将无法重复使用,并且您可能还会遇到某些软件包的问题。
我看了一眼问题的评论,我看到了一些问题:
(
我意识到你的用户模型与原始数据模型不匹配,因为在用户模型中有 get_medical_profile
、get_patient_profile
和 get_physiotherapist_profile
函数,你假设任何用户可以同时拥有多个个人资料,这既不会反映在您使用 OneToOneField 的个人资料模型(医疗、患者和物理治疗师)中,也不会反映在问题的原始数据模型中,这是关于抽象的重要事情 class -责任。要求(根据下面的模型)似乎是 "one user can have only one profile".
所以..我认为这可以通过一种简单明了的方式解决,您不需要参与整体身份验证 esquema,如组和权限或向用户模型添加其他属性:
class UserProfile(models.Model):
user = models.OneToOneField(User)
# common fields shared by medical, patient and physiotherapist profiles
class MedicalUser(models.Model):
profile = models.OneToOneField(UserProfile)
# medical fields here
class PatientUser(models.Model):
profile = models.OneToOneField(UserProfile)
# patient fields here
class PhysiotherapistUser(models.Model):
profile = models.ForeignKey(UserProfile)
# patient fields here
如您所见,您可以拥有一个配置文件,其中包含所有配置文件共享的公共字段。每个配置文件都有一个特定的模型。
此外,您可以通过下面这个小功能检查用户是否医疗,如果没有与个人资料关联的医疗资料,那么它会引发异常,这意味着它是一个未指定的个人资料:
def is_medical_profile(profile):
try:
profile.medical_user
return True
except:
return False
您也可以通过这种方式在您的模板中使用它(作为自定义模板标签):
{% if profile | is_medical_profile %}
使用这种方法你不需要设置AUTH_USER_MODEL
我希望这会改进您的解决方案。
补充说明:
以防万一您决定拥有自定义用户模型,设置 settings.AUTH_USER_MODEL 并将其用于用户的外键。
在很棒的书的一段文字上 Two scoops of Django 说:
From Django 1.5 onwards, the official preferred way to attach ForeignKey, OneToOneField, or ManyToManyField to User
因此,您的用户配置文件模型将更改如下:
from django.conf import settings
from django.db import models
class UserProfile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL)
是的,它看起来有点奇怪,但这是 Django 官方文档的建议。
@geoom @Ire @lorenzo-peña 我通过 Django 管理站点创建了一个用户,并通过 [=] 检查了他们的属性(is_medical、is_patient、is_physiotherapist) 27=]shell
In [6]: User.objects.filter(username='agarcial').values('is_medical','is_patient','is_physiotherapist')
Out[6]: [{'is_physiotherapist': True, 'is_patient': True, 'is_medical': True}]
目前,在我的 views.py 中,只有当用户属于三种用户类型(医疗、患者或物理治疗师)之一时,我才会登录
# Create your views here.
class ProfileView(LoginRequiredMixin, TemplateView):
template_name = 'profile.html'
def get_context_data(self, **kwargs):
self.request.session['Hi'] = True
context = super(ProfileView, self).get_context_data(**kwargs)
is_auth = False
name = None
# Check if in the request goes the user
user = self.request.user
# Check about of possible cases (For now is one profile)
if user.is_medical:
#if self.request.user.is_authenticated():
print (user.is_medical)
is_auth = True
profile=user.get_medical_profile()
#name = self.request.user.username
data = {
'is_auth':is_auth,
'profile':profile,
}
context.update({'userprofile':profile, 'data':data})
elif user.is_patient:
print (user.is_patient)
is_auth=True
profile=user.get_patient_profile()
data = {
'is_auth':is_auth,
'profile':profile,
}
context.update({'userprofile':profile,'data':data})
elif user.is_physiotherapist:
print (user.is_physiotherapist)
is_auth=True
profile=user.get_physiotherapist_profile()
data = {
'is_auth':is_auth,
'profile':profile,
}
context.update({'userprofile':profile,'data':data})
return context
def get_userprofile(self):
return self.request.user.userprofile
如果我检查其他可能的组合(用户患者、医生和物理治疗师)这可行吗?
我想为(医生、患者、物理治疗师)创建组并为授权主题绑定用户,尽管我应该审查授权过程的其他事情,例如 django guardian?
这个怎么样?