We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Render only first-leveled children at the header menu
Now we have too many categories at the header menu
![image](https://user-images.githubusercontent.com/3526796/65932829-d6c31280-e417-11e9-8b01-3ec7f32c76b5.png)


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `shopelectro/logic/header.py`
Content:
```
1 from django.conf import settings
2 from django.db.models import Q
3 
4 from pages import models as pages_models
5 from shopelectro import models
6 
7 
8 def menu_qs() -> pages_models.PageQuerySet:
9     """
10     QuerySet with header menu items.
11 
12     Contains root categories.
13     Result can be tuned HEADER_LINKS settings option.
14     """
15     return (
16         pages_models.Page.objects.active()
17         .filter(
18             Q(slug__in=settings.HEADER_LINKS['add'])
19             | (
20                 # @todo #974:30m  Optimize the header menu query.
21                 #  Fetch catalog page for the header menu at the same query.
22                 #  root category pages.
23                 Q(parent=pages_models.CustomPage.objects.filter(slug='catalog'))
24                 & Q(type='model')
25                 & Q(related_model_name=models.Category._meta.db_table)
26                 & ~Q(slug__in=settings.HEADER_LINKS['exclude'])
27             )
28         )
29         .order_by('position')
30     )
31
```

Path: `shopelectro/templatetags/se_extras.py`
Content:
```
1 import datetime
2 import math
3 
4 from django import template
5 from django.conf import settings
6 from django.contrib.humanize.templatetags.humanize import intcomma
7 from django.template.defaultfilters import floatformat
8 from django.urls import reverse
9 
10 from images.models import ImageMixin
11 from pages.models import Page
12 from shopelectro import logic
13 
14 register = template.Library()
15 
16 
17 @register.simple_tag
18 def roots():
19     return logic.header.menu_qs()
20 
21 
22 @register.simple_tag
23 def footer_links():
24     return settings.FOOTER_LINKS
25 
26 
27 @register.filter
28 def class_name(model):
29     """Return Model name."""
30     return type(model).__name__
31 
32 
33 @register.simple_tag
34 def time_to_call():
35     def is_weekend(t):
36         return t.weekday() > 4
37 
38     def is_friday(t):
39         return t.weekday() == 4
40 
41     def not_yet_opened(t):
42         current_time = (t.hour, t.minute)
43         open_time = (10, 00)
44         return current_time < open_time and not is_weekend(t)
45 
46     def is_closed(t):
47         current_time = (t.hour, t.minute)
48         closing_time = (16, 30) if is_friday(t) else (17, 30)
49         return current_time > closing_time
50 
51     when_we_call = {
52         lambda now: is_weekend(now) or (is_friday(now) and is_closed(now)): 'В понедельник в 10:30',
53         lambda now: not_yet_opened(now): 'Сегодня в 10:30',
54         lambda now: is_closed(now) and not (is_friday(now) or is_weekend(now)): 'Завтра в 10:30',
55         lambda _: True: 'В течение 30 минут'
56     }
57 
58     time_ = datetime.datetime.now()
59     call = ' позвонит менеджер и обсудит детали доставки.'
60     for condition, time in when_we_call.items():
61         if condition(time_):
62             return time + call
63 
64 
65 @register.simple_tag
66 def full_url(url_name, *args):
67     return settings.BASE_URL + reverse(url_name, args=args)
68 
69 
70 @register.filter
71 def humanize_price(price):
72     return intcomma(floatformat(price, 0))
73 
74 
75 @register.filter
76 def show_price_in_units(item):
77     if (getattr(item, 'in_pack', 1) > 1):
78         return 'руб / упаковка'
79     return 'руб / шт'
80 
81 
82 # Not good code, but duker at 06/10/2016 don't know how to fix it.
83 # It makes Image model very complex.
84 @register.simple_tag
85 def get_img_alt(entity: ImageMixin):
86     product_alt = 'Фотография {}'
87     logo_alt = 'Логотип компании Shopelectro'
88 
89     if not isinstance(entity, Page):
90         return logo_alt
91 
92     # try one of this attributes to get pages name
93     name_attrs = ['h1', 'title', 'name']
94     entity_name = next(
95         getattr(entity, attr)
96         for attr in name_attrs
97         if getattr(entity, attr)
98     )
99     return product_alt.format(entity_name)
100 
101 
102 @register.simple_tag
103 def main_image_or_logo(page: Page):
104     """Used for microdata."""
105     if hasattr(page, 'main_image') and page.main_image:
106         return page.main_image.url
107     else:
108         return settings.STATIC_URL + 'images/logo.png'
109 
110 
111 @register.inclusion_tag('catalog/product_feedbacks_icons.html')
112 def icon_stars(rating=0):
113     """Render set of rating icons based on 1 through 5 rating values."""
114     full_icons = int(math.floor(rating))
115     half_icons = 0 if rating == int(rating) else 1
116     empty_icons = 5 - full_icons - half_icons
117 
118     return {
119         'full_icons': range(full_icons),
120         'half_icons': range(half_icons),
121         'empty_icons': range(empty_icons),
122     }
123
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/shopelectro/logic/header.py b/shopelectro/logic/header.py
--- a/shopelectro/logic/header.py
+++ b/shopelectro/logic/header.py
@@ -1,3 +1,6 @@
+import typing
+from functools import lru_cache
+
 from django.conf import settings
 from django.db.models import Q
 
@@ -5,26 +8,41 @@
 from shopelectro import models
 
 
-def menu_qs() -> pages_models.PageQuerySet:
-    """
-    QuerySet with header menu items.
+class Menu:
+    DICT_TYPE = typing.Dict[models.CategoryPage, typing.List[models.CategoryPage]]
+
+    @staticmethod
+    def roots() -> pages_models.PageQuerySet:
+        """
+        QuerySet with header menu items.
 
-    Contains root categories.
-    Result can be tuned HEADER_LINKS settings option.
-    """
-    return (
-        pages_models.Page.objects.active()
-        .filter(
-            Q(slug__in=settings.HEADER_LINKS['add'])
-            | (
-                # @todo #974:30m  Optimize the header menu query.
-                #  Fetch catalog page for the header menu at the same query.
-                #  root category pages.
-                Q(parent=pages_models.CustomPage.objects.filter(slug='catalog'))
-                & Q(type='model')
-                & Q(related_model_name=models.Category._meta.db_table)
-                & ~Q(slug__in=settings.HEADER_LINKS['exclude'])
+        Contains root categories.
+        Result can be tuned HEADER_LINKS settings option.
+        """
+        return (
+            pages_models.Page.objects.active()
+            .filter(
+                Q(slug__in=settings.HEADER_LINKS['add'])
+                | (
+                    # @todo #974:30m  Optimize the header menu query.
+                    #  Fetch catalog page for the header menu at the same query.
+                    #  root category pages.
+                    Q(parent=pages_models.CustomPage.objects.filter(slug='catalog'))
+                    & Q(type='model')
+                    & Q(related_model_name=models.Category._meta.db_table)
+                    & ~Q(slug__in=settings.HEADER_LINKS['exclude'])
+                )
             )
+            .order_by('position')
         )
-        .order_by('position')
-    )
+
+    @lru_cache(maxsize=1)
+    def as_dict(self) -> DICT_TYPE:
+        return {
+            root: list(
+                root.get_children()
+                .filter(type='model')
+                .filter(related_model_name=models.Category._meta.db_table)
+            )
+            for root in self.roots().iterator()
+        }
diff --git a/shopelectro/templatetags/se_extras.py b/shopelectro/templatetags/se_extras.py
--- a/shopelectro/templatetags/se_extras.py
+++ b/shopelectro/templatetags/se_extras.py
@@ -15,8 +15,8 @@
 
 
 @register.simple_tag
-def roots():
-    return logic.header.menu_qs()
+def header_menu() -> logic.header.Menu:
+    return logic.header.Menu()
 
 
 @register.simple_tag

{"golden_diff": "diff --git a/shopelectro/logic/header.py b/shopelectro/logic/header.py\n--- a/shopelectro/logic/header.py\n+++ b/shopelectro/logic/header.py\n@@ -1,3 +1,6 @@\n+import typing\n+from functools import lru_cache\n+\n from django.conf import settings\n from django.db.models import Q\n \n@@ -5,26 +8,41 @@\n from shopelectro import models\n \n \n-def menu_qs() -> pages_models.PageQuerySet:\n-    \"\"\"\n-    QuerySet with header menu items.\n+class Menu:\n+    DICT_TYPE = typing.Dict[models.CategoryPage, typing.List[models.CategoryPage]]\n+\n+    @staticmethod\n+    def roots() -> pages_models.PageQuerySet:\n+        \"\"\"\n+        QuerySet with header menu items.\n \n-    Contains root categories.\n-    Result can be tuned HEADER_LINKS settings option.\n-    \"\"\"\n-    return (\n-        pages_models.Page.objects.active()\n-        .filter(\n-            Q(slug__in=settings.HEADER_LINKS['add'])\n-            | (\n-                # @todo #974:30m  Optimize the header menu query.\n-                #  Fetch catalog page for the header menu at the same query.\n-                #  root category pages.\n-                Q(parent=pages_models.CustomPage.objects.filter(slug='catalog'))\n-                & Q(type='model')\n-                & Q(related_model_name=models.Category._meta.db_table)\n-                & ~Q(slug__in=settings.HEADER_LINKS['exclude'])\n+        Contains root categories.\n+        Result can be tuned HEADER_LINKS settings option.\n+        \"\"\"\n+        return (\n+            pages_models.Page.objects.active()\n+            .filter(\n+                Q(slug__in=settings.HEADER_LINKS['add'])\n+                | (\n+                    # @todo #974:30m  Optimize the header menu query.\n+                    #  Fetch catalog page for the header menu at the same query.\n+                    #  root category pages.\n+                    Q(parent=pages_models.CustomPage.objects.filter(slug='catalog'))\n+                    & Q(type='model')\n+                    & Q(related_model_name=models.Category._meta.db_table)\n+                    & ~Q(slug__in=settings.HEADER_LINKS['exclude'])\n+                )\n             )\n+            .order_by('position')\n         )\n-        .order_by('position')\n-    )\n+\n+    @lru_cache(maxsize=1)\n+    def as_dict(self) -> DICT_TYPE:\n+        return {\n+            root: list(\n+                root.get_children()\n+                .filter(type='model')\n+                .filter(related_model_name=models.Category._meta.db_table)\n+            )\n+            for root in self.roots().iterator()\n+        }\ndiff --git a/shopelectro/templatetags/se_extras.py b/shopelectro/templatetags/se_extras.py\n--- a/shopelectro/templatetags/se_extras.py\n+++ b/shopelectro/templatetags/se_extras.py\n@@ -15,8 +15,8 @@\n \n \n @register.simple_tag\n-def roots():\n-    return logic.header.menu_qs()\n+def header_menu() -> logic.header.Menu:\n+    return logic.header.Menu()\n \n \n @register.simple_tag\n", "issue": "Render only first-leveled children at the header menu\nNow we have too many categories at the header menu\r\n![image](https://user-images.githubusercontent.com/3526796/65932829-d6c31280-e417-11e9-8b01-3ec7f32c76b5.png)\r\n\n", "before_files": [{"content": "from django.conf import settings\nfrom django.db.models import Q\n\nfrom pages import models as pages_models\nfrom shopelectro import models\n\n\ndef menu_qs() -> pages_models.PageQuerySet:\n    \"\"\"\n    QuerySet with header menu items.\n\n    Contains root categories.\n    Result can be tuned HEADER_LINKS settings option.\n    \"\"\"\n    return (\n        pages_models.Page.objects.active()\n        .filter(\n            Q(slug__in=settings.HEADER_LINKS['add'])\n            | (\n                # @todo #974:30m  Optimize the header menu query.\n                #  Fetch catalog page for the header menu at the same query.\n                #  root category pages.\n                Q(parent=pages_models.CustomPage.objects.filter(slug='catalog'))\n                & Q(type='model')\n                & Q(related_model_name=models.Category._meta.db_table)\n                & ~Q(slug__in=settings.HEADER_LINKS['exclude'])\n            )\n        )\n        .order_by('position')\n    )\n", "path": "shopelectro/logic/header.py"}, {"content": "import datetime\nimport math\n\nfrom django import template\nfrom django.conf import settings\nfrom django.contrib.humanize.templatetags.humanize import intcomma\nfrom django.template.defaultfilters import floatformat\nfrom django.urls import reverse\n\nfrom images.models import ImageMixin\nfrom pages.models import Page\nfrom shopelectro import logic\n\nregister = template.Library()\n\n\n@register.simple_tag\ndef roots():\n    return logic.header.menu_qs()\n\n\n@register.simple_tag\ndef footer_links():\n    return settings.FOOTER_LINKS\n\n\n@register.filter\ndef class_name(model):\n    \"\"\"Return Model name.\"\"\"\n    return type(model).__name__\n\n\n@register.simple_tag\ndef time_to_call():\n    def is_weekend(t):\n        return t.weekday() > 4\n\n    def is_friday(t):\n        return t.weekday() == 4\n\n    def not_yet_opened(t):\n        current_time = (t.hour, t.minute)\n        open_time = (10, 00)\n        return current_time < open_time and not is_weekend(t)\n\n    def is_closed(t):\n        current_time = (t.hour, t.minute)\n        closing_time = (16, 30) if is_friday(t) else (17, 30)\n        return current_time > closing_time\n\n    when_we_call = {\n        lambda now: is_weekend(now) or (is_friday(now) and is_closed(now)): '\u0412 \u043f\u043e\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u0438\u043a \u0432 10:30',\n        lambda now: not_yet_opened(now): '\u0421\u0435\u0433\u043e\u0434\u043d\u044f \u0432 10:30',\n        lambda now: is_closed(now) and not (is_friday(now) or is_weekend(now)): '\u0417\u0430\u0432\u0442\u0440\u0430 \u0432 10:30',\n        lambda _: True: '\u0412 \u0442\u0435\u0447\u0435\u043d\u0438\u0435 30 \u043c\u0438\u043d\u0443\u0442'\n    }\n\n    time_ = datetime.datetime.now()\n    call = ' \u043f\u043e\u0437\u0432\u043e\u043d\u0438\u0442 \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440 \u0438 \u043e\u0431\u0441\u0443\u0434\u0438\u0442 \u0434\u0435\u0442\u0430\u043b\u0438 \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0438.'\n    for condition, time in when_we_call.items():\n        if condition(time_):\n            return time + call\n\n\n@register.simple_tag\ndef full_url(url_name, *args):\n    return settings.BASE_URL + reverse(url_name, args=args)\n\n\n@register.filter\ndef humanize_price(price):\n    return intcomma(floatformat(price, 0))\n\n\n@register.filter\ndef show_price_in_units(item):\n    if (getattr(item, 'in_pack', 1) > 1):\n        return '\u0440\u0443\u0431 / \u0443\u043f\u0430\u043a\u043e\u0432\u043a\u0430'\n    return '\u0440\u0443\u0431 / \u0448\u0442'\n\n\n# Not good code, but duker at 06/10/2016 don't know how to fix it.\n# It makes Image model very complex.\n@register.simple_tag\ndef get_img_alt(entity: ImageMixin):\n    product_alt = '\u0424\u043e\u0442\u043e\u0433\u0440\u0430\u0444\u0438\u044f {}'\n    logo_alt = '\u041b\u043e\u0433\u043e\u0442\u0438\u043f \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438 Shopelectro'\n\n    if not isinstance(entity, Page):\n        return logo_alt\n\n    # try one of this attributes to get pages name\n    name_attrs = ['h1', 'title', 'name']\n    entity_name = next(\n        getattr(entity, attr)\n        for attr in name_attrs\n        if getattr(entity, attr)\n    )\n    return product_alt.format(entity_name)\n\n\n@register.simple_tag\ndef main_image_or_logo(page: Page):\n    \"\"\"Used for microdata.\"\"\"\n    if hasattr(page, 'main_image') and page.main_image:\n        return page.main_image.url\n    else:\n        return settings.STATIC_URL + 'images/logo.png'\n\n\n@register.inclusion_tag('catalog/product_feedbacks_icons.html')\ndef icon_stars(rating=0):\n    \"\"\"Render set of rating icons based on 1 through 5 rating values.\"\"\"\n    full_icons = int(math.floor(rating))\n    half_icons = 0 if rating == int(rating) else 1\n    empty_icons = 5 - full_icons - half_icons\n\n    return {\n        'full_icons': range(full_icons),\n        'half_icons': range(half_icons),\n        'empty_icons': range(empty_icons),\n    }\n", "path": "shopelectro/templatetags/se_extras.py"}], "after_files": [{"content": "import typing\nfrom functools import lru_cache\n\nfrom django.conf import settings\nfrom django.db.models import Q\n\nfrom pages import models as pages_models\nfrom shopelectro import models\n\n\nclass Menu:\n    DICT_TYPE = typing.Dict[models.CategoryPage, typing.List[models.CategoryPage]]\n\n    @staticmethod\n    def roots() -> pages_models.PageQuerySet:\n        \"\"\"\n        QuerySet with header menu items.\n\n        Contains root categories.\n        Result can be tuned HEADER_LINKS settings option.\n        \"\"\"\n        return (\n            pages_models.Page.objects.active()\n            .filter(\n                Q(slug__in=settings.HEADER_LINKS['add'])\n                | (\n                    # @todo #974:30m  Optimize the header menu query.\n                    #  Fetch catalog page for the header menu at the same query.\n                    #  root category pages.\n                    Q(parent=pages_models.CustomPage.objects.filter(slug='catalog'))\n                    & Q(type='model')\n                    & Q(related_model_name=models.Category._meta.db_table)\n                    & ~Q(slug__in=settings.HEADER_LINKS['exclude'])\n                )\n            )\n            .order_by('position')\n        )\n\n    @lru_cache(maxsize=1)\n    def as_dict(self) -> DICT_TYPE:\n        return {\n            root: list(\n                root.get_children()\n                .filter(type='model')\n                .filter(related_model_name=models.Category._meta.db_table)\n            )\n            for root in self.roots().iterator()\n        }\n", "path": "shopelectro/logic/header.py"}, {"content": "import datetime\nimport math\n\nfrom django import template\nfrom django.conf import settings\nfrom django.contrib.humanize.templatetags.humanize import intcomma\nfrom django.template.defaultfilters import floatformat\nfrom django.urls import reverse\n\nfrom images.models import ImageMixin\nfrom pages.models import Page\nfrom shopelectro import logic\n\nregister = template.Library()\n\n\n@register.simple_tag\ndef header_menu() -> logic.header.Menu:\n    return logic.header.Menu()\n\n\n@register.simple_tag\ndef footer_links():\n    return settings.FOOTER_LINKS\n\n\n@register.filter\ndef class_name(model):\n    \"\"\"Return Model name.\"\"\"\n    return type(model).__name__\n\n\n@register.simple_tag\ndef time_to_call():\n    def is_weekend(t):\n        return t.weekday() > 4\n\n    def is_friday(t):\n        return t.weekday() == 4\n\n    def not_yet_opened(t):\n        current_time = (t.hour, t.minute)\n        open_time = (10, 00)\n        return current_time < open_time and not is_weekend(t)\n\n    def is_closed(t):\n        current_time = (t.hour, t.minute)\n        closing_time = (16, 30) if is_friday(t) else (17, 30)\n        return current_time > closing_time\n\n    when_we_call = {\n        lambda now: is_weekend(now) or (is_friday(now) and is_closed(now)): '\u0412 \u043f\u043e\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u0438\u043a \u0432 10:30',\n        lambda now: not_yet_opened(now): '\u0421\u0435\u0433\u043e\u0434\u043d\u044f \u0432 10:30',\n        lambda now: is_closed(now) and not (is_friday(now) or is_weekend(now)): '\u0417\u0430\u0432\u0442\u0440\u0430 \u0432 10:30',\n        lambda _: True: '\u0412 \u0442\u0435\u0447\u0435\u043d\u0438\u0435 30 \u043c\u0438\u043d\u0443\u0442'\n    }\n\n    time_ = datetime.datetime.now()\n    call = ' \u043f\u043e\u0437\u0432\u043e\u043d\u0438\u0442 \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440 \u0438 \u043e\u0431\u0441\u0443\u0434\u0438\u0442 \u0434\u0435\u0442\u0430\u043b\u0438 \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0438.'\n    for condition, time in when_we_call.items():\n        if condition(time_):\n            return time + call\n\n\n@register.simple_tag\ndef full_url(url_name, *args):\n    return settings.BASE_URL + reverse(url_name, args=args)\n\n\n@register.filter\ndef humanize_price(price):\n    return intcomma(floatformat(price, 0))\n\n\n@register.filter\ndef show_price_in_units(item):\n    if (getattr(item, 'in_pack', 1) > 1):\n        return '\u0440\u0443\u0431 / \u0443\u043f\u0430\u043a\u043e\u0432\u043a\u0430'\n    return '\u0440\u0443\u0431 / \u0448\u0442'\n\n\n# Not good code, but duker at 06/10/2016 don't know how to fix it.\n# It makes Image model very complex.\n@register.simple_tag\ndef get_img_alt(entity: ImageMixin):\n    product_alt = '\u0424\u043e\u0442\u043e\u0433\u0440\u0430\u0444\u0438\u044f {}'\n    logo_alt = '\u041b\u043e\u0433\u043e\u0442\u0438\u043f \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438 Shopelectro'\n\n    if not isinstance(entity, Page):\n        return logo_alt\n\n    # try one of this attributes to get pages name\n    name_attrs = ['h1', 'title', 'name']\n    entity_name = next(\n        getattr(entity, attr)\n        for attr in name_attrs\n        if getattr(entity, attr)\n    )\n    return product_alt.format(entity_name)\n\n\n@register.simple_tag\ndef main_image_or_logo(page: Page):\n    \"\"\"Used for microdata.\"\"\"\n    if hasattr(page, 'main_image') and page.main_image:\n        return page.main_image.url\n    else:\n        return settings.STATIC_URL + 'images/logo.png'\n\n\n@register.inclusion_tag('catalog/product_feedbacks_icons.html')\ndef icon_stars(rating=0):\n    \"\"\"Render set of rating icons based on 1 through 5 rating values.\"\"\"\n    full_icons = int(math.floor(rating))\n    half_icons = 0 if rating == int(rating) else 1\n    empty_icons = 5 - full_icons - half_icons\n\n    return {\n        'full_icons': range(full_icons),\n        'half_icons': range(half_icons),\n        'empty_icons': range(empty_icons),\n    }\n", "path": "shopelectro/templatetags/se_extras.py"}]}