我为多个角色或用户类型设置了用户自定义模型,例如:
我的用户模型是这样的:
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(r'^dashboard/', DashboardProfileView.as_view(), name='dashboard'),
但问题是当系统尝试渲染accounts/preferences/username
URL时,该URL是为了向所有用户查看帐户选项而不考虑用户类型而设置的。
在我的urls.py中有两个网址帐号/
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(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