我在Ubuntu 12.04上使用Django 1.4和Python 2.7。
我有一个模板,我想填写有关项目开发人员的信息。
每位开发人员都将显示以下信息:
type
title
first_name
last_name
skills
我遇到的麻烦是每个开发人员都有很多与之相关的技能。
我已经创建了这样的模型:
class DevSkills(models.Model):
dev = models.ForeignKey(User)
skill = models.CharField(max_length = 200)
我正在尝试创建一个将填充字典的视图,以便我可以遍历每个开发人员,显示他们的信息,然后遍历每个技能(一次显示一个)。
以下是观点:
def developers(request):
"""
.. function:: developers()
Provide the page that shows the developer credentials
:param request: Django Request object
"""
devs = User.objects.filter(is_staff = True)
dev_info = {}
for dev in devs:
dev_info.update(createDevDisplayDict(dev))
data = { 'user' : request.user }
data.update({ 'devs' : dev_info })
return render_to_response("developers.html", data)
我已指定is_staff
中的User
字段,表示该用户是开发人员。
我创建了一个简单的实用程序,可以帮助我填充嵌入的词典,以便我可以遍历它们:
def createDevDisplayDict(user):
"""
.. function:: createDevDisplayDict()
Create a dictionary for showcasing the developer
:param user: developer who we are working with
"""
userProfile = UserProfile.objects.get(user = user)
devSkills = DevSkills.objects.filter(dev = user)
dev_dict = {}
user_dict = { 'dev_type' : userProfile.dev_type,
'title' : userProfile.title,
'first_name' : user.first_name,
'last_name' : user.last_name,
}
dev_dict.update(user_dict)
skill_dict = {}
for skill in devSkills:
skill_dict.upate({ 'skill' : skill.skill })
dev_dict.update(skill_dict)
return dev_dict
我的目的是遍历每个开发人员,创建一个“超级”字典来包含他们的user_dict
字典(基于他们的User
信息)并为每个字典添加一个字典他们的技能。然后,回到模板中,我想循环遍历“超级”字典,以便它们呈现如下内容:
James Taylor
Project Lead
Software Developer
• Django
• Python
• JavaScript
• JQuery
Elizabeth Norton
Design Lead
Graphic Designer
• Edge
• Adobe Photoshop
• Adobe Illustrator
• CSS
以下是我正在尝试使用的模板:
{% extends "base.html" %}
{% block content %}
<div>
<p>Our Developers</p>
</div>
{% for dev in devs %}
{{ dev.user_dict.first_name }} {{ dev.user_dict.last_name }}
{{ dev.user_dict.title }}
{{ dev.user_dict.dev_type }}
<ul>
{% for skill in dev.skill_dict %}
<li>skill.skill</li>
{% endfor %}
</ul>
{% endfor %}
{% endblock %}
当我看到页面时,它看起来像这样:
Our Developers
是的......没有任何人填充。有什么建议吗?
更新1: 我根据iMom0的建议修改了我的实用程序。我现在使用列表来包含每项技能。像这样:
def createDevDisplayDict(user):
"""
.. function:: createDevDisplayDict()
Create a dictionary for showcasing the developer
:param user: developer who we are working with
"""
userProfile = UserProfile.objects.get(user = user)
devSkills = DevSkills.objects.filter(dev = user)
dev_dict = {}
user_dict = { 'dev_type' : userProfile.dev_type,
'title' : userProfile.title,
'first_name' : user.first_name,
'last_name' : user.last_name,
}
dev_dict.update(user_dict)
skills = []
for skill in devSkills:
skills.append(skill.skill)
skill_dict = {'skill' : skills}
dev_dict.update(skill_dict)
return dev_dict
我可以看到这样做的价值 - 事实上,它更加直观,而且我认为我在另一方面做得太难了。但我的模板仍显示裸露。 :(
更新2:
我知道我现在正在写道。我在视图中添加了一些日志记录:
devs = User.objects.filter(is_staff = True, is_superuser = False)
dev_info = {}
for dev in devs:
dev_info.update(createDevDisplayDict(dev))
for key in dev_info:
for sub_key in dev_info[key]:
logfile.write('{0} = {1}\n'.format(sub_key, dev_info[key][sub_key]))
日志文件显示:
skills = [u'Java', u'Perl', u'C++', u'Python', u'Django']
dev_type = Software Developer
first_name = Rico
last_name = Cordova
title = Owner
所以,它必须是我在模板中调用它的方式,对吧?
更新3:
我意识到我正在断开user_dict
及其skills
的连接。所以我稍微修改了实用程序,将它们放入一个字典中。
## Create a logging object
userProfile = UserProfile.objects.get(user = user)
devSkills = DevSkills.objects.filter(dev = user)
dev_dict = {}
user_dict = { 'dev_type' : userProfile.dev_type,
'title' : userProfile.title,
'first_name' : user.first_name,
'last_name' : user.last_name,
}
skills = []
for skill in devSkills:
skills.append(skill.skill)
user_dict.update({ 'skills' : skills })
dev_dict['user_dict'] = user_dict
return dev_dict
在我看来,这是一个更好的解决方案。我仍然无法访问模板中的user_dict
信息。 :(
答案 0 :(得分:2)
你可以使用Django的ORM功能让这更容易(而且,我们会看到,获得更好的性能),这是一个很棒的功能!
class DevSkill(models.Model):
dev = models.ForeignKey(UserProfile, related_name = 'skill_set')
skill = models.CharField(max_length = 200)
我们改变了两件事:
UserProfile
ForeignKey
代替用户将简化其余代码。由于您有UserProfile
&lt; - &gt;无论如何User
映射,这不会成为一个问题。related_name
属性,以便任何UserProfile
对象现在都有skill_set
属性,该属性存储DevSkills
的列表。 (请注意,related_name
不是必需的,如果您没有设置,Django将创建一个通用的modelname_set
属性。
此外,DevSkill
应该是单数,对象是单一技能!
我还希望您对UserProfile
有以下内容,并假设您创建了代码。如果不这样做,你需要适应。
class UserProfile(models.Model):
user = models.OneToOneField(User)
title = models.CharField(max_length = 40)
dev_type = # W/E you want
devs = UserProfile.objects.all() # Or W/E queryset would fit.
# Pass context & all.
{% extends "base.html" %}
{% block content %}
<div>
<p>Our Developers</p>
</div>
{% for dev in devs %}
{{ dev.user.first_name }} {{ dev.user.last_name }}
{{ dev.title }}
{{ dev.dev_type }}
<ul>
{% for skill in dev.skill_set.all %}
<li>skill.skill</li>
{% endfor %}
</ul>
{% endfor %}
{% endblock %}
请注意,此代码(您现在正在使用的代码)将绝对会破坏性能。实际上,我们正在为每个用户进行多次查询(为他们的用户和他们的DevSkills访问数据库)。
但这不是问题,我们可以使用ORM的select_related
和prefetch_related
功能来解决这个问题:
devs = UserProfile.objects.select_related('user').prefetch_related('skill_set').all()
这样,我们只执行两个查询,一个用于UserProfile
- &gt; User
和DevSkill
的一个,加入是用Python完成的,但你不应该关心它,Django会为你做。
请注意prefetch_related
是Django 1.4的功能。
脚注:UserProfile
内容在Django 1.5中消失,请查看!
答案 1 :(得分:1)
dict.update
始终覆盖dict的值
In [2]: d = {'key': 'value'}
In [3]: d.update({'key': 'value1'})
In [4]: d
Out[4]: {'key': 'value1'}
相反,您应该使用list
和list.append
。
您的模板不知道user_dict
是什么,更正,
dev_dict['user_dict'] = user_dict
答案 2 :(得分:0)
这是我的新概念 - 模板中的dict.items
。以下是我能够展示我想要的内容。
{% extends "base.html" %}
{% block content %}
<div>
<p>Our Developers</p>
</div>
{% for key, value in devs.items %}
{{ value.first_name }} {{ value.last_name }} <br>
{{ value.title }} <br>
{{ value.dev_type }} <br>
<ul>
{% for skill in value.skills %}
<li>{{ skill }}</li>
{% endfor %}
</ul>
{% endfor %}
{% endblock %}