在我的项目中,我有两种形式:“学生”和“教授”,在这两个模型中我都宣称@property是这样的:
class Professor(User):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
birthday = models.DateField("Data de Nascimento")
sexChoices = (
(u"1", "Masculino"),
(u"2", "Feminino"),
)
sex = models.CharField(max_length = 1, choices = sexoChoices, default = u"1")
def __str__(self):
return self.user.username
@property
def perf(self):
""" This property call the profile name """
return '%s' % 'Professor'
之后我创建了一个方法调用get_profile(),如下所示:
def get_profile(user):
""" defines the kind of profile
Example:
from roles.models import *
user = User.objects.all()
profile = get_profile(user[1])
profile.perfil
"""
try:
professor = Professor.objects.get(username=user.username)
return professor
except:
pass
try:
student = Student.objects.get(username=user.username)
return student
except:
pass
return user
在我的登录视图中,我正在尝试渲染不同的html,为此,我正在使用get_profile()和perf属性,如下所示:
class LoginValidator(View):
def post(self, request, **kwargs):
username = request.POST['username']
password = request.POST['password']
user = authenticate(request, username=username, password=password)
if user is not None:
if user.is_active:
login(request, user)
messages.success(request, 'Logado com sucesso')
if( get_profile(user).perf == 'Professor'):
return render(request,'professor/home.html')
return render(request,'student/home.html')
else:
messages.error(request, 'Usuário não encontrado')
所以我的问题是:为什么这种方法不起作用?有更好的方法来实现这个吗?
我也对替代方式感到满意。
观测值:。我正在使用Django 1.11和Python 3.5.2
答案 0 :(得分:0)
使用hasattr()属性可以很好地与OneToOneField配合使用。 see here in doc
只需将这段代码放入models.py
即可def get_profile(self):
if(hasattr(self, 'profile')):
return self.profile
return None
注意:强> 您使用教授作为OneToOne字段。我在这里使用个人资料,因为我假设会有多种模式,一个是教授。另外,我在配置文件字段中没有看到related_name属性。将related_name属性设置为:
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True, related_name = 'profile')
从文档中引用:您还可以使用hasattr来避免异常捕获的需要:
此方法适用于用户模型对象。之所以如此,是因为用户模型对象与配置文件模型对象具有OneToOne关系。 希望这可以帮助。感谢。