用django查询命中MySQL数据库的次数太多了

Ed.*_*Ed. 3 python mysql django

我正在使用django-favorites来提取用户所拥有的对象列表.该应用程序有一个模型和一个经理

class FavoriteManager(models.Manager):
    """ A Manager for Favorites
    """
    def favorites_for_user(self, user):
        """ Returns Favorites for a specific user
        """
        return self.get_query_set().filter(user=user)

class Favorite(models.Model):
    user = models.ForeignKey(User)
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = generic.GenericForeignKey('content_type', 'object_id')

    created_on = models.DateTimeField(auto_now_add=True)

    objects = FavoriteManager()

    class Meta:
        verbose_name = _('favorite')
        verbose_name_plural = _('favorites')
        unique_together = (('user', 'content_type', 'object_id'),)

    def __unicode__(self):
        return "%s added %s as a favorite" % (self.user, self.content_object)
Run Code Online (Sandbox Code Playgroud)

在我看来,我正在为用户拉扯最爱

 from favorites.models import Favorite
 def myfavorites(request):

      item = Favorite.objects.favorites_for_user(user=request.user)

      return render_to_response('myfavorites.html', {
           'favorites':item
      },
      context_instance=RequestContext(request))
Run Code Online (Sandbox Code Playgroud)

在我的模板中,我尝试获取收藏夹及其模型类型的列表:

{% for fave in favorites %}
    {{ fave.content_type }}<br>
    {{ fave.content_object }}<br><br>
{% endfor %}
Run Code Online (Sandbox Code Playgroud)

但是使用django调试工具栏,我发现每次循环我都会访问数据库两次.代码正在查询数据库中的content_type和content_object,以获取favorites对象中的每个fave.

如何优化代码以便数据被拉一次而无需对数据库进行多次点击以检索信息?

jpi*_*pic 9

您可以在以下几种解决方

  1. 通用关系预取,您可以使用此示例应用程序的此代码段.

  2. 标识映射/缓存,使用内容类型和对象ID,使键缓存模型,这里是一个例子,你可以拿里面的代码__getstate__,并__setstate__做出一个模板标签,这是你能找到的最快的解决方案

  3. 直接获取关系,在某些时候,您可能需要本文中详述的解决方案之一,以便在以后使用外键时进行通用关系性能.

  4. 使用JonhyCache,JohnyCache是一个用于查询的缓存框架,它与django缓存抽象一起使用.我还没有亲自尝试过,因为这三个解决方案在我的项目中已经足够了.

  5. 缓存模板片段,减少hacky,它看起来像处理这种产生大量查询的问题的官方方式,并且当用户更改他的收藏夹时,您可以使缓存版本无效.

请注意,select_related()不适用于泛型关系.这是因为相关对象可以在任何表中,因此无法在纯sql中进行正确的连接.通用关系是Django的一个特性,而不是来自MySQL.