0

我的模型.py:

from django.db import models
from django.contrib.auth.models import User


class SkillCategory(models.Model):
    title = models.CharField(max_length=255)

    def __unicode__(self):
        return self.title

    class Meta:
        verbose_name_plural = "Skill Categories"


class Skill(models.Model):
    title = models.CharField(max_length=255)
    category = models.ForeignKey(
        SkillCategory, default=None, null=True, blank=True
    )

    def __unicode__(self):
        return self.title


class UserProfile(models.Model):
    user = models.OneToOneField(User)
    skill = models.ManyToManyField(Skill)
    avatar = models.URLField(
        max_length=400, default=None, null=True, blank=True
    )

    def __unicode__(self):
        return self.user.username

我的意见.py:

def ShowUserProfile(request, username=None, template_name='user_profile.html'):
    if not username:
         username = request.user.username

    profile = get_object_or_404(
        UserProfile.objects.select_related(), user__username=username
    )
    ...

在我的模板中,我像这样迭代:

 ...
 {% if skill.category.title == 'Some Skill' %}
   {% for skill in profile.skill.all %}
     <li>{{ skill }}</li>
   {% endfor %}
 {% endif %}
 ...

但是,如果我查看 Django 调试工具栏,我发现对于每个SkillDjango 都在查询 db 以获取Category. 我select_relatedUserProfile对象上使用,但它不影响查询的数量。肯定有更好的方法,让 Django 可以一次性获取所有Skill相关的SkillCategory参考资料?

编辑

根据准确的反馈,正确的视图如下所示:

def ShowUserProfile(request, username=None, template_name='user_profile.html'):
    if not username:
         username = request.user.username
    profile = get_object_or_404(
        UserProfile.objects.prefetch_related(
            'skill__category'), user__username=username
    )
4

2 回答 2

2

select_related不处理多对多关系。查看prefetch_related,它通过运行两个查询并在 Python 中加入结果来处理 ManyToMany 字段。

select_related 通过创建 SQL 连接并在 SELECT 语句中包含相关对象的字段来工作。为此,select_related 获取同一数据库查询中的相关对象。但是,为了避免通过“多”关系连接而产生更大的结果集,select_related 仅限于单值关系 - 外键和一对一。

另一方面,prefetch_related 对每个关系进行单独的查找,并在 Python 中进行“加入”。除了 select_related 支持的外键和一对一关系之外,这允许它预取多对多和多对一对象,这是使用 select_related 无法完成的。它还支持预取 GenericRelation 和 GenericForeignKey。

于 2013-10-08T20:21:37.510 回答
1

Djangoselect_related不适用于many-to-many关系。查看prefetch_related

于 2013-10-08T20:23:27.613 回答