Guest User

Untitled

a guest
Jan 24th, 2019
134
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.57 KB | None | 0 0
  1. from django.db import models
  2. from django.db.models import F, Q
  3. from django.db.models.functions import Greatest
  4. from django.contrib.auth.models import AbstractUser
  5. from django.utils import timezone
  6.  
  7.  
  8. # Create your models here.
  9. # Код отформатирован в PyCharm
  10.  
  11.  
  12. class ProductManager(models.Manager):
  13. def get_ordered_products(self, start_price=1000, end_price=10000):
  14. now = timezone.now()
  15. """
  16. Проверка что скидка активна
  17. """
  18. brand_discount = Q(Q(brand__discount__date_end__gte=now) & Q(brand__discount__date_start__lte=now))
  19.  
  20. category_discount = Q(Q(category__discount__date_end__gte=now) & Q(category__discount__date_start__lte=now))
  21.  
  22. discount = Q(Q(discount__date_end__gte=now) & Q(discount__date_start__lte=now))
  23. """
  24. Брать продукты у которых вообще нет скидки
  25. """
  26. no_discount = Q(Q(brand__discount__isnull=True) & Q(category__discount__isnull=True) & Q(discount__isnull=True))
  27.  
  28. """
  29. Аннотирование запроса, всё в одном словаре
  30. """
  31. annotations = {
  32. 'brand_discount': F('brand__discount__discount'), # Скидка по бренду
  33. 'category_discount': F('category__discount__discount'),# Скидка по категории
  34. 'self_discount': F('discount__discount'), # Собственная скидка
  35. # Полная цена вычесляется от собственной цены - максимальная скидка
  36. # 0 нужен для того, что бы в случае отсутсвия скидок, из цены на вычетался None
  37. 'full_price': F('price') - Greatest(0, 'brand_discount', 'category_discount', 'self_discount')
  38. }
  39.  
  40. return self.get_queryset().filter(brand_discount | category_discount | discount | no_discount) \
  41. .annotate(**annotations) \
  42. .filter(full_price__gte=start_price, full_price__lte=end_price) \
  43. .order_by('full_price')
  44.  
  45.  
  46. class Discount(models.Model):
  47. date_start = models.DateTimeField(verbose_name='Начало действия скидки')
  48. date_end = models.DateTimeField(verbose_name='Конец действия скидки')
  49. discount = models.DecimalField(verbose_name='Скидка', max_digits=10, decimal_places=2)
  50.  
  51. class Meta:
  52. verbose_name = 'Скидка'
  53. verbose_name_plural = 'Скидки'
  54.  
  55. def __repr__(self):
  56. return f'<{self.discount} {self.date_start} {self.date_end}>'
  57.  
  58.  
  59. class Customer(AbstractUser):
  60. discount = models.ForeignKey(Discount, verbose_name='Скидка', null=True, blank=True, on_delete=models.SET_NULL)
  61.  
  62. class Meta:
  63. verbose_name = 'Пользователь'
  64. verbose_name_plural = 'Пользователи'
  65.  
  66. def __str__(self):
  67. return self.email
  68.  
  69.  
  70. class Category(models.Model):
  71. name = models.CharField('Группа товара', max_length=64)
  72. discount = models.ForeignKey(Discount, verbose_name='Скидка', null=True, blank=True, on_delete=models.SET_NULL)
  73.  
  74. class Meta:
  75. verbose_name_plural = 'Категории'
  76. verbose_name = 'Категория'
  77.  
  78. def __repr__(self):
  79. return f'<{self.name}>'
  80.  
  81.  
  82. class Brand(models.Model):
  83. name = models.CharField('Бренд', max_length=64)
  84. discount = models.ForeignKey(Discount, verbose_name='Скидка', null=True, blank=True, on_delete=models.SET_NULL)
  85.  
  86. class Meta:
  87. verbose_name_plural = 'Бренды'
  88. verbose_name = 'Бренд'
  89.  
  90. def __repr__(self):
  91. return f'<{self.name}>'
  92.  
  93.  
  94. class Product(models.Model):
  95. category = models.ForeignKey(Category, verbose_name='Группа', null=True, blank=True,
  96. on_delete=models.SET_NULL, related_name='products')
  97. brand = models.ForeignKey(Brand, verbose_name='Бренд', related_name='products',
  98. null=True, blank=True, on_delete=models.SET_NULL)
  99. discount = models.ForeignKey(Discount, verbose_name='Скидка', null=True, blank=True,
  100. on_delete=models.SET_NULL, related_name='products')
  101. name = models.CharField('Название товара', max_length=128)
  102. price = models.DecimalField('Стоимость единицы, руб.', max_digits=10, decimal_places=2)
  103.  
  104. objects = ProductManager()
  105.  
  106. class Meta:
  107. verbose_name_plural = 'Товары'
  108. verbose_name = 'Товар'
  109.  
  110. def __repr__(self):
  111. return f'<{self.name} {self.price}>'
Add Comment
Please, Sign In to add comment