我有这样的模型
class Employee(models.Model):
"""Employee information."""
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='employee', unique=True)
position = models.CharField("current position in a company", max_length=64, blank=True)
birth_date = models.DateField("date of birth", null=True)
skills = models.ManyToManyField(
Technology, through="Skill", verbose_name="skills", blank=True)
class Technology(models.Model):
"""Technologies."""
name = models.CharField('technology name', max_length=32, unique=True)
class Skill(models.Model):
"""Information about an employee's skills."""
LEVELS = (
('basic', 'Basic'),
('intermediate', 'Intermediate'),
('advanced', 'Advanced'),
('expert', 'Expert'),
)
employee = models.ForeignKey(
Employee, on_delete=models.CASCADE, related_name="employee_skills")
technology = models.ForeignKey(Technology, on_delete=models.CASCADE)
start_date = models.DateField(
verbose_name='Works with since:')
level = models.CharField("level", max_length=64, choices=LEVELS)
我不明白为什么我的模板代码不起作用
template.html
{{ user.employee.position }}
{{ user.employee.birth_date }}
{{ user.employee.summary }}
{% for i in user.employee.skills.all %}
{{ i.technology.name }}
{{ i.level }}
{% endfor %}
我绝对看不到。所有型号都可以在adminpanel上看到。然后我使用诸如
的TemplateViewclass AccountView(TemplateView):
template_name = "profile.html"
def get_context_data(self, **kwargs):
context = super(AccountView, self).get_context_data(**kwargs)
context['skills'] =
Skill.objects.filter(employee__user=self.request.user)
return context
然后一切正常。
答案 0 :(得分:2)
您的员工模型当前与用户具有一对多关系
class Employee(models.Model):
"""Employee information."""
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='employee', unique=True)
根据您的评论,您需要一对一的关系,因此您需要将其更改为使用OneToOneField
而不是ForeignKey
从概念上讲,这类似于具有unique = True的ForeignKey,但是关系的“反向”侧将直接返回单个对象。
答案 1 :(得分:2)
建模存在问题。您应该在OneToOneField
和Employee
之间使用User
。本质上,OneToOneField
是唯一 ForeignKey
。但是,它将更改某些逻辑,例如user.employee
将访问相关的Employee
对象,而不是QuerySet
个对象中的Employee
:
class Employee(models.Model):
# ...
user = models.OneToOneField(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
related_name='employee'
)
# ...
在您的AccountView
中,您将'skills'
与该员工的技能统一在一起,实际上是:
class AccountView(TemplateView):
template_name = "profile.html"
def get_context_data(self, **kwargs):
context = super(AccountView, self).get_context_data(**kwargs)
context.update(
skills=Skill.objects.filter(employee__user=self.request.user).select_related('technology')
)
return context
您可能想在这里使用.select_related(..)
来防止所谓的“ N + 1问题”,其中对于每一项 技能,您都会多查询。
因此您可以通过以下方式呈现技能:
{% for skill in skills %}
{{ skill.technology.name }}
{{ skill.level }}
{% endfor %}
或者您可以通过以下方式访问:
{% for skill in request.user.employee.employee_skills.all %}
{{ skill.technology.name }}
{{ skill.level }}
{% endfor %}
尽管上述方法不太安全,因为User
可能没有相关的Employee
对象。