admin.py
class OrderItemInline(admin.TabularInline):
model = OrderItem
raw_id_fields = ['product']
extra = 1 # Количество пустых форм для добавления новых элементов
fields = ['product_image','product','product_article_number','size','product_mesto','product_zacup_price','quantity', 'price','get_cost']
readonly_fields = ['product_image','product_article_number','product_mesto','product_zacup_price','get_cost']
def get_queryset(self, request):
queryset = super().get_queryset(request).select_related('product', 'size').prefetch_related(
'product__images',
'product__product_prices',
)
# # Для отладки: выводим информацию о загруженных элементах
# for item in queryset:
# # Получаем все размеры и цены, связанные с продуктом
# all_sizes = item.product.product_prices.all() # Получаем все ProductPrice для текущего продукта
# sizes_list = ', '.join([f"{price.size.title}" for price in all_sizes]) # Формируем список размеров и цен
# print(f"Заказ: {item.order}, Продукт: {item.product.title}, "
# f"Артикул: {item.product.article_number}, Выбранный размер: {item.size.title if item.size else 'Нет размера'}, "
# f"Все размеры {sizes_list}")
return queryset
def product_article_number(self, obj):
return obj.product.article_number if obj.product and obj.product.article_number else 'Артикул не указан'
product_article_number.short_description = 'Артикул'
def product_mesto(self, obj):
return obj.product.mesto if obj.product and obj.product.mesto else 'Место не указано'
product_mesto.short_description = 'Место'
def product_image(self, obj):
# Получаем все изображения заранее
images = obj.product.images.all() # Используем предзагруженные изображения
if images:
first_image = images[0]
return mark_safe(f"<img src='{first_image.image.url}' width='50'>")
else:
return 'Нет фото'
product_image.short_description = 'Фото товара'
# def product_image(self, obj):
# # Используем предзагруженные изображения
# if obj.product and hasattr(obj.product, 'images'):
# images = obj.product.images.all() # Используем предзагруженные изображения
# if images:
# first_image = images[0]
# return mark_safe(f"<img src='{first_image.image.url}' width='50'>")
# return 'Нет фото'
# product_image.short_description = 'Фото товара'
@admin.register(Order)
class OrderAdmin(admin.ModelAdmin):
list_display = [
'id',
'first_name_last_name',
'email',
'paid',
'status',
'phone',
'region',
'city',
'address',
'postal_code',
'get_total_cost',
'get_total_zakup_cost',
order_pdf,
]
list_editable = ['paid','status',]
readonly_fields = ['get_total_zakup_cost','get_total_cost']
list_filter = ['paid', 'created', 'updated']
inlines = [OrderItemInline]
search_fields = ['items__product__article_number','first_name_last_name', 'email', 'phone','city']
list_display_links=['id','first_name_last_name',]
def get_queryset(self, request):
# Загружаем связанные модели для оптимизации запросов
queryset = super().get_queryset(request).select_related('delivery_method', 'discount').prefetch_related(
'items__product',
'items__size',
)
models.py
class OrderItem(models.Model):
order = models.ForeignKey(Order,related_name='items',on_delete=models.CASCADE, db_index=True)
product = models.ForeignKey(Product,related_name='order_items', on_delete=models.CASCADE,verbose_name="Название товара", db_index=True)
price = models.DecimalField(max_digits=10,decimal_places=0, verbose_name="Цена", db_index=True)
quantity = models.PositiveIntegerField(default=1,verbose_name="Количество", db_index=True)
size = models.ForeignKey(Size, on_delete=models.SET_NULL, null=True, verbose_name="Размер", db_index=True) # Изменено на ForeignKey
def __str__(self):
return str(self.product.title)
class Size(models.Model):
title = models.CharField(max_length=50, unique=True,verbose_name="Размеры",db_index=True) # Название размера
def __str__(self):
return f"{self.title}"
class Meta:
verbose_name = 'Размер'
verbose_name_plural = 'Размеры'
class ProductPrice(models.Model):
product = models.ForeignKey('Product', related_name='product_prices', on_delete=models.CASCADE)
size = models.ForeignKey(Size, related_name='product_size', on_delete=models.CASCADE,verbose_name='Размер')
price = models.DecimalField(max_digits=10, decimal_places=0,verbose_name='Цена продажи',db_index=True)
old_price = models.DecimalField(max_digits=10, decimal_places=0, verbose_name='Цена старая ', null=True, blank=True,db_index=True)
zacup_price = models.DecimalField(max_digits=10, decimal_places=0,verbose_name='Цена закупки',db_index=True)
def __str__(self):
return f"{self.product.title}"
И вот что выводит django-toolbar:
SELECT ••• FROM "home_product" WHERE "home_product"."id" = 596 LIMIT 21
5 similar queries. 0,31
Sel Expl
+
SELECT ••• FROM "home_size" INNER JOIN "home_productprice" ON ("home_size"."id" = "home_productprice"."size_id") WHERE "home_productprice"."product_id" = 596
5 similar queries. 0,34
Sel Expl
+
SELECT ••• FROM "home_product" WHERE "home_product"."id" = 336 LIMIT 21
5 similar queries. 0,42
Sel Expl
+
SELECT ••• FROM "home_size" INNER JOIN "home_productprice" ON ("home_size"."id" = "home_productprice"."size_id") WHERE "home_productprice"."product_id" = 336
5 similar queries. 0,23
Sel Expl
+
SELECT ••• FROM "home_product" WHERE "home_product"."id" = 338 LIMIT 21
5 similar queries. 0,27
Sel Expl
+
SELECT ••• FROM "home_size" INNER JOIN "home_productprice" ON ("home_size"."id" = "home_productprice"."size_id") WHERE "home_productprice"."product_id" = 338
5 similar queries. 0,26
Sel Expl
+
SELECT ••• FROM "home_product" WHERE "home_product"."id" = 193 LIMIT 21
5 similar queries. 0,32
Sel Expl
+
SELECT ••• FROM "home_size" INNER JOIN "home_productprice" ON ("home_size"."id" = "home_productprice"."size_id") WHERE "home_productprice"."product_id" = 193
5 similar queries. 0,24
Sel Expl
+
SELECT ••• FROM "home_product" WHERE "home_product"."id" = 179 LIMIT 21
5 similar queries. 0,30
Sel Expl
+
SELECT ••• FROM "home_size" INNER JOIN "home_productprice" ON ("home_size"."id" = "home_productprice"."size_id") WHERE "home_productprice"."product_id" = 179
5 similar queries. 0,28
Sel Expl
+
SELECT ••• FROM "home_size"
2 similar queries. Duplicated 2 times. 0,47
Sel Expl
+
SELECT ••• FROM "home_size"
2 similar queries. Duplicated 2 times.
Лог вывода консоли:
April 06, 2025 - 13:44:24
Django version 5.1.4, using settings 'myshop.settings'
Starting development server at http://127.0.0.1:8002/
Quit the server with CONTROL-C.
(0.001) SELECT "django_session"."session_key", "django_session"."session_data", "django_session"."expire_date" FROM "django_session" WHERE ("django_session"."expire_date" > '2025-04-06 10:44:27.429400' AND "django_session"."session_key" = 'py3lis56k2ne7ase9jp1thi03aza6d44') LIMIT 21; args=('2025-04-06 10:44:27.429400', 'py3lis56k2ne7ase9jp1thi03aza6d44'); alias=default
(0.001) SELECT "users_user"."id", "users_user"."password", "users_user"."last_login", "users_user"."is_superuser", "users_user"."username", "users_user"."first_name", "users_user"."last_name", "users_user"."email", "users_user"."is_staff", "users_user"."is_active", "users_user"."date_joined", "users_user"."phone", "users_user"."region", "users_user"."city", "users_user"."address", "users_user"."postal_code", "users_user"."photo", "users_user"."delivery_method_id" FROM "users_user" WHERE "users_user"."id" = 1 LIMIT 21; args=(1,); alias=default
(0.003) BEGIN; args=None; alias=default
(0.000) SELECT "home_productprice"."id", "home_productprice"."product_id", "home_productprice"."size_id", "home_productprice"."price", "home_productprice"."old_price", "home_productprice"."zacup_price", "home_product"."id", "home_product"."title", "home_product"."description", "home_product"."article_number", "home_product"."stock", "home_product"."unit", "home_product"."is_hidden", "home_product"."mesto", "home_product"."created", "home_product"."updated", "home_product"."slug", "home_product"."category_id", "home_size"."id", "home_size"."title" FROM "home_productprice" INNER JOIN "home_product" ON ("home_productprice"."product_id" = "home_product"."id") INNER JOIN "home_size" ON ("home_productprice"."size_id" = "home_size"."id"); args=(); alias=default
(0.000) SELECT "orders_order"."id", "orders_order"."first_name_last_name", "orders_order"."email", "orders_order"."phone", "orders_order"."region", "orders_order"."city", "orders_order"."address", "orders_order"."postal_code", "orders_order"."passport_number", "orders_order"."comment", "orders_order"."my_comment", "orders_order"."created", "orders_order"."updated", "orders_order"."paid", "orders_order"."zamena_product", "orders_order"."strahovat_gruz", "orders_order"."soglasie_na_obrabotku_danyh", "orders_order"."soglasie_na_uslovie_sotrudnichestva", "orders_order"."status", "orders_order"."delivery_method_id", "orders_order"."price_delivery", "orders_order"."discount_id", "orders_deliverymethod"."id", "orders_deliverymethod"."title", "orders_discount"."id", "orders_discount"."discount_type", "orders_discount"."discount_value" FROM "orders_order" LEFT OUTER JOIN "orders_deliverymethod" ON ("orders_order"."delivery_method_id" = "orders_deliverymethod"."id") LEFT OUTER JOIN "orders_discount" ON ("orders_order"."discount_id" = "orders_discount"."id") WHERE "orders_order"."id" = 21 LIMIT 21; args=(21,); alias=default
(0.000) SELECT "orders_orderitem"."id", "orders_orderitem"."order_id", "orders_orderitem"."product_id", "orders_orderitem"."price", "orders_orderitem"."quantity", "orders_orderitem"."size_id" FROM "orders_orderitem" WHERE "orders_orderitem"."order_id" IN (21); args=(21,); alias=default
(0.000) SELECT "home_product"."id", "home_product"."title", "home_product"."description", "home_product"."article_number", "home_product"."stock", "home_product"."unit", "home_product"."is_hidden", "home_product"."mesto", "home_product"."created", "home_product"."updated", "home_product"."slug", "home_product"."category_id" FROM "home_product" WHERE "home_product"."id" IN (193, 336, 338, 179, 596); args=(193, 336, 338, 179, 596); alias=default
(0.000) SELECT "home_size"."id", "home_size"."title" FROM "home_size" WHERE "home_size"."id" IN (17, 18, 11, 12); args=(17, 18, 11, 12); alias=default
(0.000) SELECT "orders_orderitem"."id", "orders_orderitem"."order_id", "orders_orderitem"."product_id", "orders_orderitem"."price", "orders_orderitem"."quantity", "orders_orderitem"."size_id", "home_product"."id", "home_product"."title", "home_product"."description", "home_product"."article_number", "home_product"."stock", "home_product"."unit", "home_product"."is_hidden", "home_product"."mesto", "home_product"."created", "home_product"."updated", "home_product"."slug", "home_product"."category_id", "home_size"."id", "home_size"."title" FROM "orders_orderitem" INNER JOIN "home_product" ON ("orders_orderitem"."product_id" = "home_product"."id") LEFT OUTER JOIN "home_size" ON ("orders_orderitem"."size_id" = "home_size"."id") WHERE "orders_orderitem"."order_id" = 21 ORDER BY "orders_orderitem"."id" ASC; args=(21,); alias=default
(0.000) SELECT "home_productimage"."id", "home_productimage"."product_id", "home_productimage"."image" FROM "home_productimage" WHERE "home_productimage"."product_id" IN (596, 336, 338, 193, 179); args=(596, 336, 338, 193, 179); alias=default
(0.000) SELECT "home_productprice"."id", "home_productprice"."product_id", "home_productprice"."size_id", "home_productprice"."price", "home_productprice"."old_price", "home_productprice"."zacup_price" FROM "home_productprice" WHERE "home_productprice"."product_id" IN (596, 336, 338, 193, 179); args=(596, 336, 338, 193, 179); alias=default
(0.000) SELECT "django_content_type"."id", "django_content_type"."app_label", "django_content_type"."model" FROM "django_content_type" WHERE ("django_content_type"."app_label" = 'orders' AND "django_content_type"."model" = 'order') LIMIT 21; args=('orders', 'order'); alias=default
(0.000) COMMIT; args=None; alias=default
(0.000) SELECT "orders_deliverymethod"."id", "orders_deliverymethod"."title" FROM "orders_deliverymethod"; args=(); alias=default
(0.000) SELECT "orders_discount"."id", "orders_discount"."discount_type", "orders_discount"."discount_value" FROM "orders_discount"; args=(); alias=default
Общая стоимость до применения скидки: 138260
Скидка не найдена.
(0.000) SELECT "home_product"."id", "home_product"."title", "home_product"."description", "home_product"."article_number", "home_product"."stock", "home_product"."unit", "home_product"."is_hidden", "home_product"."mesto", "home_product"."created", "home_product"."updated", "home_product"."slug", "home_product"."category_id" FROM "home_product" WHERE "home_product"."id" = 596 LIMIT 21; args=(596,); alias=default
(0.000) SELECT "home_size"."id", "home_size"."title" FROM "home_size" INNER JOIN "home_productprice" ON ("home_size"."id" = "home_productprice"."size_id") WHERE "home_productprice"."product_id" = 596; args=(596,); alias=default
(0.000) SELECT "home_product"."id", "home_product"."title", "home_product"."description", "home_product"."article_number", "home_product"."stock", "home_product"."unit", "home_product"."is_hidden", "home_product"."mesto", "home_product"."created", "home_product"."updated", "home_product"."slug", "home_product"."category_id" FROM "home_product" WHERE "home_product"."id" = 336 LIMIT 21; args=(336,); alias=default
(0.000) SELECT "home_size"."id", "home_size"."title" FROM "home_size" INNER JOIN "home_productprice" ON ("home_size"."id" = "home_productprice"."size_id") WHERE "home_productprice"."product_id" = 336; args=(336,); alias=default
(0.000) SELECT "home_product"."id", "home_product"."title", "home_product"."description", "home_product"."article_number", "home_product"."stock", "home_product"."unit", "home_product"."is_hidden", "home_product"."mesto", "home_product"."created", "home_product"."updated", "home_product"."slug", "home_product"."category_id" FROM "home_product" WHERE "home_product"."id" = 338 LIMIT 21; args=(338,); alias=default
(0.000) SELECT "home_size"."id", "home_size"."title" FROM "home_size" INNER JOIN "home_productprice" ON ("home_size"."id" = "home_productprice"."size_id") WHERE "home_productprice"."product_id" = 338; args=(338,); alias=default
(0.000) SELECT "home_product"."id", "home_product"."title", "home_product"."description", "home_product"."article_number", "home_product"."stock", "home_product"."unit", "home_product"."is_hidden", "home_product"."mesto", "home_product"."created", "home_product"."updated", "home_product"."slug", "home_product"."category_id" FROM "home_product" WHERE "home_product"."id" = 193 LIMIT 21; args=(193,); alias=default
(0.000) SELECT "home_size"."id", "home_size"."title" FROM "home_size" INNER JOIN "home_productprice" ON ("home_size"."id" = "home_productprice"."size_id") WHERE "home_productprice"."product_id" = 193; args=(193,); alias=default
(0.000) SELECT "home_product"."id", "home_product"."title", "home_product"."description", "home_product"."article_number", "home_product"."stock", "home_product"."unit", "home_product"."is_hidden", "home_product"."mesto", "home_product"."created", "home_product"."updated", "home_product"."slug", "home_product"."category_id" FROM "home_product" WHERE "home_product"."id" = 179 LIMIT 21; args=(179,); alias=default
(0.000) SELECT "home_size"."id", "home_size"."title" FROM "home_size" INNER JOIN "home_productprice" ON ("home_size"."id" = "home_productprice"."size_id") WHERE "home_productprice"."product_id" = 179; args=(179,); alias=default
(0.000) SELECT "home_size"."id", "home_size"."title" FROM "home_size"; args=(); alias=default
(0.000) SELECT "home_size"."id", "home_size"."title" FROM "home_size"; args=(); alias=default
(0.000) BEGIN; args=None; alias=default
(0.000) UPDATE "django_session" SET "session_data" = '.eJxVjEEOgyAQRe_CuiEQBAaX3fcMZmaAYttoIroy3t2SuGi3_73_djHgtpZhq2kZxih6ocXtdyPkd5oaiC-cnrPkeVqXkWRT5EWrfMwxfe6X-xcoWMv3zZS6rEA7MOh96AyQy-Qj22AVsNXeg82AELRBtg7J50ScFAanbNeijMsq-v04ThvvOzo:1u1NUK:ywIzO6wpEw_wDhVAGLX_8a7TY0iwQsqO-SDnkIJd21s', "expire_date" = '2025-04-20 10:44:28.630942' WHERE "django_session"."session_key" = 'py3lis56k2ne7ase9jp1thi03aza6d44'; args=('.eJxVjEEOgyAQRe_CuiEQBAaX3fcMZmaAYttoIroy3t2SuGi3_73_djHgtpZhq2kZxih6ocXtdyPkd5oaiC-cnrPkeVqXkWRT5EWrfMwxfe6X-xcoWMv3zZS6rEA7MOh96AyQy-Qj22AVsNXeg82AELRBtg7J50ScFAanbNeijMsq-v04ThvvOzo:1u1NUK:ywIzO6wpEw_wDhVAGLX_8a7TY0iwQsqO-SDnkIJd21s', '2025-04-20 10:44:28.630942', 'py3lis56k2ne7ase9jp1thi03aza6d44'); alias=default
(0.020) COMMIT; args=None; alias=default
[06/Apr/2025 13:44:28] "GET /admin/orders/order/21/change/ HTTP/1.1" 200 87405
(0.001) SELECT "django_session"."session_key", "django_session"."session_data", "django_session"."expire_date" FROM "django_session" WHERE ("django_session"."expire_date" > '2025-04-06 10:44:28.682638' AND "django_session"."session_key" = 'py3lis56k2ne7ase9jp1thi03aza6d44') LIMIT 21; args=('2025-04-06 10:44:28.682638', 'py3lis56k2ne7ase9jp1thi03aza6d44'); alias=default
(0.001) SELECT "users_user"."id", "users_user"."password", "users_user"."last_login", "users_user"."is_superuser", "users_user"."username", "users_user"."first_name", "users_user"."last_name", "users_user"."email", "users_user"."is_staff", "users_user"."is_active", "users_user"."date_joined", "users_user"."phone", "users_user"."region", "users_user"."city", "users_user"."address", "users_user"."postal_code", "users_user"."photo", "users_user"."delivery_method_id" FROM "users_user" WHERE "users_user"."id" = 1 LIMIT 21; args=(1,); alias=default
[06/Apr/2025 13:44:28] "GET /admin/jsi18n/ HTTP/1.1" 200 17546