Как лучше всего использовать prefetch_related с мультинаследованием и несколькими типами скидок для сайта электронной коммерции?

У меня есть следующие модели: class Theme(models.Model): name = mode.charfield()

class Category(mdoesl):
    name = models.charfield()

class Product(models.Model):
    title = models.charfield()

class Course(Product):
     ..........
class LtProduct(Product):
    category = models.ForeignKey(Category)
    theme = models.ForeginKey(Theme)

class CouponCode(models.Model):
    code = models.Charfield(unique = True)
    .........
class ProductDiscount(models.Model):
    product = models.ForeignKey(Product)
    codes = models.ManyToManyField(CouponCode)

class CategoryDiscount(models.Model):
     category = models.ForeignKey(Category)

class ThemeDiscount(models.Model):
     theme = models.ForeignKey(Theme)

class UserCoupon(models.Model):
    user = models.OneToOneField(User)
    code = models.ForeignKey(CouonCode)
    is_used = models.BooleanField(default = False)

Что я хочу сделать здесь, это сначала получить код пользователя и проверить, может ли этот код быть применен для добавления этого продукта в корзину пользователя, а также получить категорию и тему, связанные с этим продуктом, и с их скидками и кодами тоже, вот что я пытался решить это

product = Product.objects.prefetch_related('course', 'lvproduct__category__categorydiscount_set__codes', 'lvproduct__theme__theme_discount_set__codes','productdiscount_set__codes').get(id = product_id)

и затем я получу выкупленный пользователем код следующим образом:

user_code = UserCoupon.objects.filter(user = user, is_used = False)

и затем я проверяю по каждому типу скидки, чтобы проверить, принадлежат ли коды к этим скидкам

codes = product.productdiscount_set.codes.all()
for code in codes:
   if code == user_code:
       #do the necessary calculation
       user_code.is_used = True

если кода нет в кодах скидок продукта, то я проверю, есть ли он для категории, но так как категория связана только с LvProduct, я бы сделал так:

if not user_code.is_used:
    try:
      codes = product.lvproduct.category.categorydiscount_set.codes.all()
      #do the same thing here

и поскольку один и тот же код купона может быть использован для нескольких типов скидок, и если две скидки применимы к одному и тому же продукту, то первый тип скидки, который будет проверен первым, будет применен, так что это лучший способ достичь этого?

Надеюсь, это достаточно ясно показывает, что я пытаюсь сделать

Вернуться на верх