我将用户自定义模型设置为多个角色或用户类型,例如:
- 学生用户
- 教授用户
- 执行用户
我的用户模型是这样的:
class User(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(unique=True)
username = models.CharField(max_length=40, unique=True)
slug = models.SlugField(
max_length=100,
blank=True
)
is_student = models.BooleanField(
default=False,
verbose_name='Student',
help_text='Student profile'
)
is_professor = models.BooleanField(
default=False,
verbose_name='Professor',
help_text='Professor profile'
)
is_executive = models.BooleanField(
default=False,
verbose_name='Executive',
help_text='Executive profile',
)
other fields ...
我的 User 模型中也有一些功能,可以让我根据用户类型获取配置文件:
def get_student_profile(self):
student_profile = None
if hasattr(self, 'studentprofile'):
student_profile = self.studentprofile
return student_profile
def get_professor_profile(self):
professor_profile = None
if hasattr(self, 'professorprofile'):
professor_profile = self.professorprofile
return professor_profile
def get_executive_profile(self):
executive_profile = None
if hasattr(self, 'executiveprofile'):
executive_profile = self.executiveprofile
return executive_profile
# This method does not works. It's illustrative
# How to get the user profile in this view for send data?
def get_user_profile(self):
user_profile = None
if hasattr(self, 'user'):
user_profile = self.user
return user_profile
def save(self, *args, **kwargs):
user = super(User,self).save(*args,**kwargs)
# Creating an user with student profile
if self.is_student and not StudentProfile.objects.filter(user=self).exists():
student_profile = StudentProfile(user = self)
student_slug = self.username
student_profile.slug = student_slug
student_profile.save()
# Creating an user with professor profile
elif self.is_professor and not ProfessorProfile.objects.filter(user=self).exists():
professor_profile = ProfessorProfile(user=self)
professor_slug = self.username
professor_profile.slug = professor_slug
professor_profile.save()
# Creating an user with executive profile
elif self.is_executive and not ExecutiveProfile.objects.filter(user=self).exists():
executive_profile = ExecutiveProfile(user = self)
executive_slug = self.username
executive_profile.slug = executive_slug
executive_profile.save()
# I have this signal to get the username and assign to slug field
@receiver(post_save, sender=User)
def post_save_user(sender, instance, **kwargs):
slug = slugify(instance.username)
User.objects.filter(pk=instance.pk).update(slug=slug)
每个配置文件(Student
和Professor
)Executive
都在自己的模型中使用自己的字段进行管理:
class StudentProfile(models.Model):
user = models.OneToOneField(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE
)
class ProfessorProfile(models.Model):
user = models.OneToOneField(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE
)
class ExecutiveProfile(models.Model):
user = models.OneToOneField(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE
)
在我的身份验证过程中,我LOGIN_REDIRECT_URL = 'dashboard'
在我的设置中设置了属性,并且我有一个DashboardProfileView
类,当这些是学生或教授或执行人员时,我有一个课程会询问个人资料用户:
class DashboardProfileView(LoginRequiredMixin, TemplateView):
template_name = 'dashboard.html'
def get_context_data(self, **kwargs):
context = super(DashboardProfileView, self).get_context_data(**kwargs)
user = self.request.user
if user.is_student:
profile = user.get_student_profile()
context['userprofile'] = profile
elif user.is_professor:
profile = user.get_professor_profile()
context['userprofile'] = profile
elif user.is_executive:
profile = user.get_executive_profile()
context['userprofile'] = profile
elif user.is_study_host:
profile = user.get_study_host_profile()
context['userprofile'] = profile
elif user.is_active:
profile = user.get_user_profile()
context['userprofile'] = profile
return context
当经过身份验证的用户具有或或属性时,我的DashboardProfileView
课程运行良好。is_student
is_professor
is_executive
但是,当我在没有任何这些属性(is_student
、或is_professor
或is_executive
)的情况下创建和用户时,我的用户配置文件上下文DashboardProfileView
不会发送到模板,这是我没有获得用户的值配置文件的原因。
由于用户没有属性配置文件,我在视图中询问这种方式:
if user.is_active:
profile = user.get_user_profile()
context['userprofile'] = profile
由于创建的所有用户都将 is_active 布尔属性设置为 True,但这不起作用。
当用户不是 is_student、不是 is_professor 并且不是 is_executive 时,如何在我的视图中获取用户配置文件,这意味着,只是一个普通的 django 用户?
更新
根据@Sijan Bhandari的回答,这是正确的,context['userprofile'] = self.request.user
是询问普通用户个人资料的合适方式。这应该有效。
但是在我的基本模板中进行了这些适当的更改,我NoReverseMatch
的一些网址出现了问题,它是:
File "/home/bgarcial/.virtualenvs/ihost/lib/python3.5/site-packages/django/urls/resolvers.py", line 392, in _reverse_with_prefix
(lookup_view_s, args, kwargs, len(patterns), patterns)
django.urls.exceptions.NoReverseMatch: Reverse for 'preferences' with arguments '('',)' and keyword arguments '{}' not found. 1 pattern(s) tried: ['accounts/preferences/(?P<slug>[\\w\\-]+)/$']
[07/Apr/2017 11:52:26] "GET /dashboard/ HTTP/1.1" 500 179440
dashboard/
它是用户登录时重定向的 URL。
url(r'^dashboard/', DashboardProfileView.as_view(), name='dashboard'),
但问题在于系统尝试呈现accounts/preferences/username
URL 时,创建该 URL 是为了查看所有用户的帐户选项,而不管他们的用户类型如何。
在我的 urls.py 中有两个 urls 帐户/
url(r'^accounts/', include('accounts.urls', namespace = 'accounts')),
# Call the accounts/urls.py to other urls like preferences/
url(r'^accounts/', include('django.contrib.auth.urls'), name='login'),
# I don't assign namespace because this is django URL to pre-bult-in login function
在我的 accounts/urls.py 我有preferences/
URL:
url(r"^preferences/(?P<slug>[\w\-]+)/$",
views.AccountSettingsUpdateView.as_view(),
name='preferences'
),
在这里,我告诉用户请求一个具有slug
引用其username
字段的字段的用户。我在这个 URL 中传递了用户的 slug 以检索他们的帐户数据,我希望这个正则表达式让我可以使用大写和小写字母数字字符以及连字符和下划线
然后在我的模板中,我以这种方式放置此网址:
<li><a href="{% url 'accounts:preferences' userprofile.user.username %}">Settings</a></li>
但是,当我使用一些没有 ( is_student
, is_professor
, is_executive
) 配置文件的用户登录时,这意味着 django 普通用户,我有以下行为:
File "/home/bgarcial/.virtualenvs/ihost/lib/python3.5/site-packages/django/urls/resolvers.py", line 392, in _reverse_with_prefix
(lookup_view_s, args, kwargs, len(patterns), patterns)
django.urls.exceptions.NoReverseMatch: Reverse for 'preferences' with arguments '('',)' and keyword arguments '{}' not found. 1 pattern(s) tried: ['accounts/preferences/(?P<slug>[\\w\\-]+)/$']
[07/Apr/2017 12:12:18] "GET /dashboard/ HTTP/1.1" 500 179440