如何避免在递归时重复django sql查询

hrirmatl  于 2023-04-22  发布在  Go
关注(0)|答案(1)|浏览(125)

如何避免重复在Django中的递归过程中. Django显示了12个重复与递归SQL查询,我如何避免他们,从下面附加的代码. Е标签的任务是返回嵌套菜单

class Menu(models.Model):
    title = models.CharField(max_length=100, unique=True)
    slug = models.SlugField(unique=True, db_index=True)
    parent = models.ForeignKey(
        'self',
        related_name='kids',
        blank=True,
        null=True,
        on_delete=models.CASCADE
    )
class MenuView(TemplateView):
    template_name = 'main/menu.html'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['main_menu'] = kwargs.get('slug', None)
        return context
@register.simple_tag()
def draw_menu(slug):
    menu = Menu.objects.filter(slug=slug).prefetch_related('kids') if slug \
        else Menu.objects.filter(parent=None).prefetch_related('kids')

    return menu
{% extends 'base.html' %}

{% block title %}{{ title }}{% endblock%}

{% block content %}
{% load draw_menu %}
{% draw_menu main_menu as menu %}
<ul>
     {% for item in menu %}
          {% include "inc/menu_by_menu.html" %}
     {% endfor %}
</ul>
{% endblock %}
<li>
    {% if item.kids %}
    <a href="{{ item.slug }}">{{ item.title }}</a>
    <ul>
        {% for kid in item.kids.all %}
            {% with item=kid template_name="inc/menu_by_menu.html" %}
                   {% include template_name %}
            {% endwith %}
        {% endfor %}
    </ul>
    {% else %}
        <a href="{{ item.slug }}">{{ item.title }}</a>
    {% endif %}
</li>
tf7tbtn2

tf7tbtn21#

您可以尝试进行两个或三个级别的预取,这可能就足够了:

@register.simple_tag
def draw_menu(slug):
    qs = Menu.objects.all()
    qs = qs.filter(slug=slug) if slug else qs.filter(parent=None)
    return qs.prefetch_related('kids__kids')

Django中可以实现递归预取,查询集需要一些更新,但目前不是这样。这实际上是一个有趣的情况,没有涉及(尚未)。

相关问题