We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
tests_selenium_admin.py:146-149: Resurrect admin price...
The puzzle `822-138e7a1d` from #822 has to be resolved: 

https://github.com/fidals/shopelectro/blob/c89b807552a45099cad752b4121f40d8836eb024/shopelectro/tests/tests_selenium_admin.py#L146-L149

The puzzle was created by duker33 on 30-Apr-19. 

  

If you have any technical questions, don't ask me, submit new tickets instead. The task will be \"done\" when the problem is fixed and the text of the puzzle is _removed_ from the source code. Here is more about [PDD](http://www.yegor256.com/2009/03/04/pdd.html) and [about me](http://www.yegor256.com/2017/04/05/pdd-in-action.html). 


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

{"golden_diff": "diff --git a/shopelectro/admin.py b/shopelectro/admin.py\n--- a/shopelectro/admin.py\n+++ b/shopelectro/admin.py\n@@ -12,7 +12,7 @@\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+from generic_admin import inlines, mixins, models, sites, filters\n \n from shopelectro import models as se_models\n from shopelectro.views.admin import TableEditor\n@@ -34,6 +34,11 @@\n     return queryset.filter(**{query: value != 'yes'})\n \n \n+class ProductPriceFilter(filters.PriceRange):\n+\n+    price_lookup = 'shopelectro_product__price'\n+\n+\n class HasTagsFilter(admin.SimpleListFilter):\n \n     product_model = se_models.Product\n@@ -155,7 +160,13 @@\n     add = False\n     delete = False\n     category_page_model = se_models.CategoryPage\n-    list_filter = [*models.ProductPageAdmin.list_filter, HasTagsFilter, HasCategoryFilter]\n+    list_filter = [\n+        *models.ProductPageAdmin.list_filter,\n+        ProductPriceFilter,\n+        HasTagsFilter,\n+        HasCategoryFilter,\n+    ]\n+    list_display = ['model_id', 'name', 'custom_parent', 'price', 'links', 'is_active']\n     inlines = [ProductInline, inlines.ImageInline]\n     search_fields = [\n         'shopelectro_product__vendor_code', 'name', 'slug',\n@@ -167,10 +178,16 @@\n     model_id.short_description = _('Vendor code')\n     model_id.admin_order_field = 'shopelectro_product__vendor_code'\n \n+    def price(self, obj):\n+        return obj.model.price\n+\n+    price.short_description = _('Price')\n+    price.admin_order_field = '_product_price'\n+\n     def get_queryset(self, request):\n+        qs = super().get_queryset(request)\n         return (\n-            super(ProductPageAdmin, self)\n-            .get_queryset(request)\n+            self.add_reference_to_field_on_related_model(qs, _product_price='price')\n             .select_related('shopelectro_product')\n         )\n", "issue": "tests_selenium_admin.py:146-149: Resurrect admin price...\nThe puzzle `822-138e7a1d` from #822 has to be resolved: \n\nhttps://github.com/fidals/shopelectro/blob/c89b807552a45099cad752b4121f40d8836eb024/shopelectro/tests/tests_selenium_admin.py#L146-L149\n\nThe puzzle was created by duker33 on 30-Apr-19. \n\n  \n\nIf you have any technical questions, don't ask me, submit new tickets instead. The task will be \\\"done\\\" when the problem is fixed and the text of the puzzle is _removed_ from the source code. Here is more about [PDD](http://www.yegor256.com/2009/03/04/pdd.html) and [about me](http://www.yegor256.com/2017/04/05/pdd-in-action.html). \n\n", "before_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"}], "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, filters\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 ProductPriceFilter(filters.PriceRange):\n\n    price_lookup = 'shopelectro_product__price'\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 = [\n        *models.ProductPageAdmin.list_filter,\n        ProductPriceFilter,\n        HasTagsFilter,\n        HasCategoryFilter,\n    ]\n    list_display = ['model_id', 'name', 'custom_parent', 'price', 'links', 'is_active']\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 price(self, obj):\n        return obj.model.price\n\n    price.short_description = _('Price')\n    price.admin_order_field = '_product_price'\n\n    def get_queryset(self, request):\n        qs = super().get_queryset(request)\n        return (\n            self.add_reference_to_field_on_related_model(qs, _product_price='price')\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"}]}