We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Add sending mail action for given orders to admin panel
We have got connection issue with smtp and didn't notify 5 client
https://sentry.fidals.com/fidals/shopelectro/issues/36/

--- 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/admin.py`
Content:
```
1 from django.contrib import admin
2 from django.contrib.admin.widgets import FilteredSelectMultiple
3 from django.contrib.redirects.models import Redirect
4 from django.db import models as django_models
5 from django.urls import reverse
6 from django.utils.html import format_html
7 from django.utils.translation import ugettext_lazy as _
8 
9 from django_select2.forms import ModelSelect2Widget
10 
11 from ecommerce.models import Position
12 from pages.models import CustomPage, FlatPage, PageTemplate
13 from generic_admin import inlines, mixins, models, sites
14 
15 from shopelectro import models as se_models
16 from shopelectro.views.admin import TableEditor
17 
18 
19 class SEAdminSite(sites.SiteWithTableEditor):
20 
21     site_header = 'Shopelectro administration'
22     table_editor_view = TableEditor
23 
24 
25 def prepare_has_filter_queryset(value, db_table, queryset):
26     if not value:
27         return
28 
29     query = '{}__tags__isnull'.format(db_table)
30 
31     # Use brackets, because `Explicit is better than implicit`.
32     return queryset.filter(**{query: value != 'yes'})
33 
34 
35 class HasTagsFilter(admin.SimpleListFilter):
36 
37     product_model = se_models.Product
38     title = _('has tags')
39     parameter_name = 'has_tags'
40 
41     def lookups(self, request, model_admin):
42         return (
43             ('yes', _('Has tags')),
44             ('no', _('Has no tags')),
45         )
46 
47     def queryset(self, request, queryset):
48         return prepare_has_filter_queryset(
49             self.value(),
50             self.product_model._meta.db_table,
51             queryset
52         )
53 
54 
55 class HasCategoryFilter(admin.SimpleListFilter):
56 
57     product_model = se_models.Product
58     title = _('has category')
59     parameter_name = 'has_category'
60 
61     def lookups(self, request, model_admin):
62         return (
63             ('yes', _('Has category')),
64             ('no', _('Has no category')),
65         )
66 
67     def queryset(self, request, queryset):
68         return prepare_has_filter_queryset(
69             self.value(),
70             self.product_model._meta.db_table,
71             queryset
72         )
73 
74 
75 class TagInline(admin.StackedInline):
76 
77     model = se_models.Tag
78     extra = 0
79 
80 
81 class CategoryInline(inlines.CategoryInline):
82 
83     model = se_models.Category
84 
85     fieldsets = ((None, {
86         'classes': ('primary-chars', ),
87         'fields': (
88             ('name', 'id'),
89             ('parent', 'correct_parent_id'),
90         )
91     }),)
92 
93 
94 class ProductInline(inlines.ProductInline):
95 
96     model = se_models.Product
97 
98     formfield_overrides = {
99         django_models.ManyToManyField: {
100             'widget': FilteredSelectMultiple(verbose_name='Tags', is_stacked=False)
101         },
102     }
103 
104     fieldsets = ((None, {
105         'classes': ('primary-chars', ),
106         'fields': (
107             ('name', 'id', 'vendor_code'),
108             ('category', 'correct_category_id'),
109             ('price', 'in_stock'),
110             'is_popular',
111             ('purchase_price', 'wholesale_small'),
112             ('wholesale_medium', 'wholesale_large'),
113             'tags',
114         )
115     }),)
116 
117     def formfield_for_dbfield(self, db_field, **kwargs):
118         if db_field.name == 'category':
119             kwargs['widget'] = ModelSelect2Widget(
120                 model=se_models.Category,
121                 search_fields=[
122                     'name__icontains',
123                     'pk__startswith',
124                 ],
125             )
126         return super(ProductInline, self).formfield_for_dbfield(
127             db_field,
128             **kwargs,
129         )
130 
131 
132 class PositionInline(admin.StackedInline):
133 
134     model = Position
135 
136 
137 class CategoryPageAdmin(models.CategoryPageAdmin):
138 
139     add = True
140     delete = False
141     inlines = [CategoryInline, inlines.ImageInline]
142 
143     def get_queryset(self, request):
144         return (
145             super(CategoryPageAdmin, self)
146             .get_queryset(request)
147             .select_related('shopelectro_category')
148         )
149 
150 
151 class ProductPageAdmin(models.ProductPageAdmin):
152 
153     add = False
154     delete = False
155     category_page_model = se_models.CategoryPage
156     list_filter = [*models.ProductPageAdmin.list_filter, HasTagsFilter, HasCategoryFilter]
157     inlines = [ProductInline, inlines.ImageInline]
158     search_fields = [
159         'shopelectro_product__vendor_code', 'name', 'slug',
160     ]
161 
162     def model_id(self, obj):
163         return obj.model.vendor_code
164 
165     model_id.short_description = _('Vendor code')
166     model_id.admin_order_field = 'shopelectro_product__vendor_code'
167 
168     def get_queryset(self, request):
169         return (
170             super(ProductPageAdmin, self)
171             .get_queryset(request)
172             .select_related('shopelectro_product')
173         )
174 
175 
176 class ProductFeedbackPageAdmin(admin.ModelAdmin):
177 
178     add = False
179     delete = False
180     list_filter = ['rating']
181     list_display = ['rating', 'name', 'dignities', 'limitations', 'general', 'links']
182 
183     def links(self, obj):
184         return format_html(
185             '''
186             <a href="{url}" class="field-link" title="Посмотреть на сайте" target="_blank">
187               <i class="fa fa-link" aria-hidden="true"></i>
188             </a>
189             '''.format(url=obj.product.url))
190 
191     links.short_description = _('Link')
192 
193     def get_queryset(self, request):
194         return (
195             super(ProductFeedbackPageAdmin, self)
196             .get_queryset(request)
197             .select_related('product')
198         )
199 
200 
201 class TagGroupAdmin(admin.ModelAdmin):
202 
203     list_display = ['id', 'name', 'position', 'count_tags']
204     list_display_links = ['name']
205 
206     inlines = [TagInline]
207 
208     def get_queryset(self, request):
209         return super(TagGroupAdmin, self).get_queryset(request).prefetch_related('tags')
210 
211     def count_tags(self, obj):
212         return obj.tags.count()
213 
214 
215 class TagAdmin(admin.ModelAdmin):
216 
217     search_fields = ['id', 'name']
218     list_display = ['id', 'name', 'position', 'custom_group']
219     list_display_links = ['name']
220 
221     def get_queryset(self, request):
222         return super(TagAdmin, self).get_queryset(request).prefetch_related('group')
223 
224     def custom_group(self, obj):
225         group = obj.group
226 
227         return format_html(
228             '<a href="{url}">{group}</a>',
229             group=group,
230             url=reverse('admin:shopelectro_taggroup_change', args=(group.id, ))
231         )
232 
233     custom_group.admin_order_field = 'group'
234     custom_group.short_description = _('Group')
235 
236 
237 class OrderAdmin(mixins.PermissionsControl):
238 
239     add = False
240     inlines = [PositionInline]
241     list_display = ['id_', 'name', 'email', 'phone', 'total_price', 'payment_type', 'paid']
242     search_fields = ['name', 'email', 'phone']
243     list_display_links = ['name']
244 
245     def id_(self, obj):
246         return obj.fake_order_number
247 
248 
249 se_admin = SEAdminSite(name='se_admin')
250 se_admin.register(CustomPage, models.CustomPageAdmin)
251 se_admin.register(FlatPage, models.FlatPageAdmin)
252 se_admin.register(PageTemplate, models.CustomPageTemplateAdmin)
253 
254 se_admin.register(se_models.CategoryPage, CategoryPageAdmin)
255 se_admin.register(se_models.Order, OrderAdmin)
256 se_admin.register(se_models.ProductPage, ProductPageAdmin)
257 se_admin.register(se_models.ProductFeedback, ProductFeedbackPageAdmin)
258 se_admin.register(se_models.TagGroup, TagGroupAdmin)
259 se_admin.register(se_models.Tag, TagAdmin)
260 
261 se_admin.register(Redirect)
262
```
--- 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/admin.py b/shopelectro/admin.py
--- a/shopelectro/admin.py
+++ b/shopelectro/admin.py
@@ -1,3 +1,4 @@
+from django.conf import settings
 from django.contrib import admin
 from django.contrib.admin.widgets import FilteredSelectMultiple
 from django.contrib.redirects.models import Redirect
@@ -8,6 +9,7 @@
 
 from django_select2.forms import ModelSelect2Widget
 
+from ecommerce import mailer
 from ecommerce.models import Position
 from pages.models import CustomPage, FlatPage, PageTemplate
 from generic_admin import inlines, mixins, models, sites
@@ -234,6 +236,27 @@
     custom_group.short_description = _('Group')
 
 
+def send_order_emails(admin_model, request, order_qs):
+    for order in order_qs:
+        context = {'shop': settings.SHOP}
+        if order.email:
+            mailer.send_order(
+                subject=settings.EMAIL_SUBJECTS['order'],
+                order=order,
+                extra_context=context,
+            )
+        else:
+            mailer.send_order(
+                subject=settings.EMAIL_SUBJECTS['one_click'],
+                order=order,
+                to_customer=False,
+                extra_context=context,
+            )
+
+
+send_order_emails.short_description = _('Sends email notifications about placed orders')
+
+
 class OrderAdmin(mixins.PermissionsControl):
 
     add = False
@@ -241,6 +264,7 @@
     list_display = ['id_', 'name', 'email', 'phone', 'total_price', 'payment_type', 'paid']
     search_fields = ['name', 'email', 'phone']
     list_display_links = ['name']
+    actions = [send_order_emails]
 
     def id_(self, obj):
         return obj.fake_order_number

{"golden_diff": "diff --git a/shopelectro/admin.py b/shopelectro/admin.py\n--- a/shopelectro/admin.py\n+++ b/shopelectro/admin.py\n@@ -1,3 +1,4 @@\n+from django.conf import settings\n from django.contrib import admin\n from django.contrib.admin.widgets import FilteredSelectMultiple\n from django.contrib.redirects.models import Redirect\n@@ -8,6 +9,7 @@\n \n from django_select2.forms import ModelSelect2Widget\n \n+from ecommerce import mailer\n from ecommerce.models import Position\n from pages.models import CustomPage, FlatPage, PageTemplate\n from generic_admin import inlines, mixins, models, sites\n@@ -234,6 +236,27 @@\n     custom_group.short_description = _('Group')\n \n \n+def send_order_emails(admin_model, request, order_qs):\n+    for order in order_qs:\n+        context = {'shop': settings.SHOP}\n+        if order.email:\n+            mailer.send_order(\n+                subject=settings.EMAIL_SUBJECTS['order'],\n+                order=order,\n+                extra_context=context,\n+            )\n+        else:\n+            mailer.send_order(\n+                subject=settings.EMAIL_SUBJECTS['one_click'],\n+                order=order,\n+                to_customer=False,\n+                extra_context=context,\n+            )\n+\n+\n+send_order_emails.short_description = _('Sends email notifications about placed orders')\n+\n+\n class OrderAdmin(mixins.PermissionsControl):\n \n     add = False\n@@ -241,6 +264,7 @@\n     list_display = ['id_', 'name', 'email', 'phone', 'total_price', 'payment_type', 'paid']\n     search_fields = ['name', 'email', 'phone']\n     list_display_links = ['name']\n+    actions = [send_order_emails]\n \n     def id_(self, obj):\n         return obj.fake_order_number\n", "issue": "Add sending mail action for given orders to admin panel\nWe have got connection issue with smtp and didn't notify 5 client\r\nhttps://sentry.fidals.com/fidals/shopelectro/issues/36/\n", "before_files": [{"content": "from django.contrib import admin\nfrom django.contrib.admin.widgets import FilteredSelectMultiple\nfrom django.contrib.redirects.models import Redirect\nfrom django.db import models as django_models\nfrom django.urls import reverse\nfrom django.utils.html import format_html\nfrom django.utils.translation import ugettext_lazy as _\n\nfrom django_select2.forms import ModelSelect2Widget\n\nfrom ecommerce.models import Position\nfrom pages.models import CustomPage, FlatPage, PageTemplate\nfrom generic_admin import inlines, mixins, models, sites\n\nfrom shopelectro import models as se_models\nfrom shopelectro.views.admin import TableEditor\n\n\nclass SEAdminSite(sites.SiteWithTableEditor):\n\n    site_header = 'Shopelectro administration'\n    table_editor_view = TableEditor\n\n\ndef prepare_has_filter_queryset(value, db_table, queryset):\n    if not value:\n        return\n\n    query = '{}__tags__isnull'.format(db_table)\n\n    # Use brackets, because `Explicit is better than implicit`.\n    return queryset.filter(**{query: value != 'yes'})\n\n\nclass HasTagsFilter(admin.SimpleListFilter):\n\n    product_model = se_models.Product\n    title = _('has tags')\n    parameter_name = 'has_tags'\n\n    def lookups(self, request, model_admin):\n        return (\n            ('yes', _('Has tags')),\n            ('no', _('Has no tags')),\n        )\n\n    def queryset(self, request, queryset):\n        return prepare_has_filter_queryset(\n            self.value(),\n            self.product_model._meta.db_table,\n            queryset\n        )\n\n\nclass HasCategoryFilter(admin.SimpleListFilter):\n\n    product_model = se_models.Product\n    title = _('has category')\n    parameter_name = 'has_category'\n\n    def lookups(self, request, model_admin):\n        return (\n            ('yes', _('Has category')),\n            ('no', _('Has no category')),\n        )\n\n    def queryset(self, request, queryset):\n        return prepare_has_filter_queryset(\n            self.value(),\n            self.product_model._meta.db_table,\n            queryset\n        )\n\n\nclass TagInline(admin.StackedInline):\n\n    model = se_models.Tag\n    extra = 0\n\n\nclass CategoryInline(inlines.CategoryInline):\n\n    model = se_models.Category\n\n    fieldsets = ((None, {\n        'classes': ('primary-chars', ),\n        'fields': (\n            ('name', 'id'),\n            ('parent', 'correct_parent_id'),\n        )\n    }),)\n\n\nclass ProductInline(inlines.ProductInline):\n\n    model = se_models.Product\n\n    formfield_overrides = {\n        django_models.ManyToManyField: {\n            'widget': FilteredSelectMultiple(verbose_name='Tags', is_stacked=False)\n        },\n    }\n\n    fieldsets = ((None, {\n        'classes': ('primary-chars', ),\n        'fields': (\n            ('name', 'id', 'vendor_code'),\n            ('category', 'correct_category_id'),\n            ('price', 'in_stock'),\n            'is_popular',\n            ('purchase_price', 'wholesale_small'),\n            ('wholesale_medium', 'wholesale_large'),\n            'tags',\n        )\n    }),)\n\n    def formfield_for_dbfield(self, db_field, **kwargs):\n        if db_field.name == 'category':\n            kwargs['widget'] = ModelSelect2Widget(\n                model=se_models.Category,\n                search_fields=[\n                    'name__icontains',\n                    'pk__startswith',\n                ],\n            )\n        return super(ProductInline, self).formfield_for_dbfield(\n            db_field,\n            **kwargs,\n        )\n\n\nclass PositionInline(admin.StackedInline):\n\n    model = Position\n\n\nclass CategoryPageAdmin(models.CategoryPageAdmin):\n\n    add = True\n    delete = False\n    inlines = [CategoryInline, inlines.ImageInline]\n\n    def get_queryset(self, request):\n        return (\n            super(CategoryPageAdmin, self)\n            .get_queryset(request)\n            .select_related('shopelectro_category')\n        )\n\n\nclass ProductPageAdmin(models.ProductPageAdmin):\n\n    add = False\n    delete = False\n    category_page_model = se_models.CategoryPage\n    list_filter = [*models.ProductPageAdmin.list_filter, HasTagsFilter, HasCategoryFilter]\n    inlines = [ProductInline, inlines.ImageInline]\n    search_fields = [\n        'shopelectro_product__vendor_code', 'name', 'slug',\n    ]\n\n    def model_id(self, obj):\n        return obj.model.vendor_code\n\n    model_id.short_description = _('Vendor code')\n    model_id.admin_order_field = 'shopelectro_product__vendor_code'\n\n    def get_queryset(self, request):\n        return (\n            super(ProductPageAdmin, self)\n            .get_queryset(request)\n            .select_related('shopelectro_product')\n        )\n\n\nclass ProductFeedbackPageAdmin(admin.ModelAdmin):\n\n    add = False\n    delete = False\n    list_filter = ['rating']\n    list_display = ['rating', 'name', 'dignities', 'limitations', 'general', 'links']\n\n    def links(self, obj):\n        return format_html(\n            '''\n            <a href=\"{url}\" class=\"field-link\" title=\"\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043d\u0430 \u0441\u0430\u0439\u0442\u0435\" target=\"_blank\">\n              <i class=\"fa fa-link\" aria-hidden=\"true\"></i>\n            </a>\n            '''.format(url=obj.product.url))\n\n    links.short_description = _('Link')\n\n    def get_queryset(self, request):\n        return (\n            super(ProductFeedbackPageAdmin, self)\n            .get_queryset(request)\n            .select_related('product')\n        )\n\n\nclass TagGroupAdmin(admin.ModelAdmin):\n\n    list_display = ['id', 'name', 'position', 'count_tags']\n    list_display_links = ['name']\n\n    inlines = [TagInline]\n\n    def get_queryset(self, request):\n        return super(TagGroupAdmin, self).get_queryset(request).prefetch_related('tags')\n\n    def count_tags(self, obj):\n        return obj.tags.count()\n\n\nclass TagAdmin(admin.ModelAdmin):\n\n    search_fields = ['id', 'name']\n    list_display = ['id', 'name', 'position', 'custom_group']\n    list_display_links = ['name']\n\n    def get_queryset(self, request):\n        return super(TagAdmin, self).get_queryset(request).prefetch_related('group')\n\n    def custom_group(self, obj):\n        group = obj.group\n\n        return format_html(\n            '<a href=\"{url}\">{group}</a>',\n            group=group,\n            url=reverse('admin:shopelectro_taggroup_change', args=(group.id, ))\n        )\n\n    custom_group.admin_order_field = 'group'\n    custom_group.short_description = _('Group')\n\n\nclass OrderAdmin(mixins.PermissionsControl):\n\n    add = False\n    inlines = [PositionInline]\n    list_display = ['id_', 'name', 'email', 'phone', 'total_price', 'payment_type', 'paid']\n    search_fields = ['name', 'email', 'phone']\n    list_display_links = ['name']\n\n    def id_(self, obj):\n        return obj.fake_order_number\n\n\nse_admin = SEAdminSite(name='se_admin')\nse_admin.register(CustomPage, models.CustomPageAdmin)\nse_admin.register(FlatPage, models.FlatPageAdmin)\nse_admin.register(PageTemplate, models.CustomPageTemplateAdmin)\n\nse_admin.register(se_models.CategoryPage, CategoryPageAdmin)\nse_admin.register(se_models.Order, OrderAdmin)\nse_admin.register(se_models.ProductPage, ProductPageAdmin)\nse_admin.register(se_models.ProductFeedback, ProductFeedbackPageAdmin)\nse_admin.register(se_models.TagGroup, TagGroupAdmin)\nse_admin.register(se_models.Tag, TagAdmin)\n\nse_admin.register(Redirect)\n", "path": "shopelectro/admin.py"}], "after_files": [{"content": "from django.conf import settings\nfrom django.contrib import admin\nfrom django.contrib.admin.widgets import FilteredSelectMultiple\nfrom django.contrib.redirects.models import Redirect\nfrom django.db import models as django_models\nfrom django.urls import reverse\nfrom django.utils.html import format_html\nfrom django.utils.translation import ugettext_lazy as _\n\nfrom django_select2.forms import ModelSelect2Widget\n\nfrom ecommerce import mailer\nfrom ecommerce.models import Position\nfrom pages.models import CustomPage, FlatPage, PageTemplate\nfrom generic_admin import inlines, mixins, models, sites\n\nfrom shopelectro import models as se_models\nfrom shopelectro.views.admin import TableEditor\n\n\nclass SEAdminSite(sites.SiteWithTableEditor):\n\n    site_header = 'Shopelectro administration'\n    table_editor_view = TableEditor\n\n\ndef prepare_has_filter_queryset(value, db_table, queryset):\n    if not value:\n        return\n\n    query = '{}__tags__isnull'.format(db_table)\n\n    # Use brackets, because `Explicit is better than implicit`.\n    return queryset.filter(**{query: value != 'yes'})\n\n\nclass HasTagsFilter(admin.SimpleListFilter):\n\n    product_model = se_models.Product\n    title = _('has tags')\n    parameter_name = 'has_tags'\n\n    def lookups(self, request, model_admin):\n        return (\n            ('yes', _('Has tags')),\n            ('no', _('Has no tags')),\n        )\n\n    def queryset(self, request, queryset):\n        return prepare_has_filter_queryset(\n            self.value(),\n            self.product_model._meta.db_table,\n            queryset\n        )\n\n\nclass HasCategoryFilter(admin.SimpleListFilter):\n\n    product_model = se_models.Product\n    title = _('has category')\n    parameter_name = 'has_category'\n\n    def lookups(self, request, model_admin):\n        return (\n            ('yes', _('Has category')),\n            ('no', _('Has no category')),\n        )\n\n    def queryset(self, request, queryset):\n        return prepare_has_filter_queryset(\n            self.value(),\n            self.product_model._meta.db_table,\n            queryset\n        )\n\n\nclass TagInline(admin.StackedInline):\n\n    model = se_models.Tag\n    extra = 0\n\n\nclass CategoryInline(inlines.CategoryInline):\n\n    model = se_models.Category\n\n    fieldsets = ((None, {\n        'classes': ('primary-chars', ),\n        'fields': (\n            ('name', 'id'),\n            ('parent', 'correct_parent_id'),\n        )\n    }),)\n\n\nclass ProductInline(inlines.ProductInline):\n\n    model = se_models.Product\n\n    formfield_overrides = {\n        django_models.ManyToManyField: {\n            'widget': FilteredSelectMultiple(verbose_name='Tags', is_stacked=False)\n        },\n    }\n\n    fieldsets = ((None, {\n        'classes': ('primary-chars', ),\n        'fields': (\n            ('name', 'id', 'vendor_code'),\n            ('category', 'correct_category_id'),\n            ('price', 'in_stock'),\n            'is_popular',\n            ('purchase_price', 'wholesale_small'),\n            ('wholesale_medium', 'wholesale_large'),\n            'tags',\n        )\n    }),)\n\n    def formfield_for_dbfield(self, db_field, **kwargs):\n        if db_field.name == 'category':\n            kwargs['widget'] = ModelSelect2Widget(\n                model=se_models.Category,\n                search_fields=[\n                    'name__icontains',\n                    'pk__startswith',\n                ],\n            )\n        return super(ProductInline, self).formfield_for_dbfield(\n            db_field,\n            **kwargs,\n        )\n\n\nclass PositionInline(admin.StackedInline):\n\n    model = Position\n\n\nclass CategoryPageAdmin(models.CategoryPageAdmin):\n\n    add = True\n    delete = False\n    inlines = [CategoryInline, inlines.ImageInline]\n\n    def get_queryset(self, request):\n        return (\n            super(CategoryPageAdmin, self)\n            .get_queryset(request)\n            .select_related('shopelectro_category')\n        )\n\n\nclass ProductPageAdmin(models.ProductPageAdmin):\n\n    add = False\n    delete = False\n    category_page_model = se_models.CategoryPage\n    list_filter = [*models.ProductPageAdmin.list_filter, HasTagsFilter, HasCategoryFilter]\n    inlines = [ProductInline, inlines.ImageInline]\n    search_fields = [\n        'shopelectro_product__vendor_code', 'name', 'slug',\n    ]\n\n    def model_id(self, obj):\n        return obj.model.vendor_code\n\n    model_id.short_description = _('Vendor code')\n    model_id.admin_order_field = 'shopelectro_product__vendor_code'\n\n    def get_queryset(self, request):\n        return (\n            super(ProductPageAdmin, self)\n            .get_queryset(request)\n            .select_related('shopelectro_product')\n        )\n\n\nclass ProductFeedbackPageAdmin(admin.ModelAdmin):\n\n    add = False\n    delete = False\n    list_filter = ['rating']\n    list_display = ['rating', 'name', 'dignities', 'limitations', 'general', 'links']\n\n    def links(self, obj):\n        return format_html(\n            '''\n            <a href=\"{url}\" class=\"field-link\" title=\"\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043d\u0430 \u0441\u0430\u0439\u0442\u0435\" target=\"_blank\">\n              <i class=\"fa fa-link\" aria-hidden=\"true\"></i>\n            </a>\n            '''.format(url=obj.product.url))\n\n    links.short_description = _('Link')\n\n    def get_queryset(self, request):\n        return (\n            super(ProductFeedbackPageAdmin, self)\n            .get_queryset(request)\n            .select_related('product')\n        )\n\n\nclass TagGroupAdmin(admin.ModelAdmin):\n\n    list_display = ['id', 'name', 'position', 'count_tags']\n    list_display_links = ['name']\n\n    inlines = [TagInline]\n\n    def get_queryset(self, request):\n        return super(TagGroupAdmin, self).get_queryset(request).prefetch_related('tags')\n\n    def count_tags(self, obj):\n        return obj.tags.count()\n\n\nclass TagAdmin(admin.ModelAdmin):\n\n    search_fields = ['id', 'name']\n    list_display = ['id', 'name', 'position', 'custom_group']\n    list_display_links = ['name']\n\n    def get_queryset(self, request):\n        return super(TagAdmin, self).get_queryset(request).prefetch_related('group')\n\n    def custom_group(self, obj):\n        group = obj.group\n\n        return format_html(\n            '<a href=\"{url}\">{group}</a>',\n            group=group,\n            url=reverse('admin:shopelectro_taggroup_change', args=(group.id, ))\n        )\n\n    custom_group.admin_order_field = 'group'\n    custom_group.short_description = _('Group')\n\n\ndef send_order_emails(admin_model, request, order_qs):\n    for order in order_qs:\n        context = {'shop': settings.SHOP}\n        if order.email:\n            mailer.send_order(\n                subject=settings.EMAIL_SUBJECTS['order'],\n                order=order,\n                extra_context=context,\n            )\n        else:\n            mailer.send_order(\n                subject=settings.EMAIL_SUBJECTS['one_click'],\n                order=order,\n                to_customer=False,\n                extra_context=context,\n            )\n\n\nsend_order_emails.short_description = _('Sends email notifications about placed orders')\n\n\nclass OrderAdmin(mixins.PermissionsControl):\n\n    add = False\n    inlines = [PositionInline]\n    list_display = ['id_', 'name', 'email', 'phone', 'total_price', 'payment_type', 'paid']\n    search_fields = ['name', 'email', 'phone']\n    list_display_links = ['name']\n    actions = [send_order_emails]\n\n    def id_(self, obj):\n        return obj.fake_order_number\n\n\nse_admin = SEAdminSite(name='se_admin')\nse_admin.register(CustomPage, models.CustomPageAdmin)\nse_admin.register(FlatPage, models.FlatPageAdmin)\nse_admin.register(PageTemplate, models.CustomPageTemplateAdmin)\n\nse_admin.register(se_models.CategoryPage, CategoryPageAdmin)\nse_admin.register(se_models.Order, OrderAdmin)\nse_admin.register(se_models.ProductPage, ProductPageAdmin)\nse_admin.register(se_models.ProductFeedback, ProductFeedbackPageAdmin)\nse_admin.register(se_models.TagGroup, TagGroupAdmin)\nse_admin.register(se_models.Tag, TagAdmin)\n\nse_admin.register(Redirect)\n", "path": "shopelectro/admin.py"}]}