2

I use Oscar 1.6.4 version. I want to override PercentageDiscountBenefit in oscar.app.offer.benefits.py. But conflict error happens. How can I override this functions?

from oscar.core.loading import get_classes

CorePercentageDiscountBenefit, CoreAbsoluteDiscountBenefit = get_classes('offer.benefits', ['PercentageDiscountBenefit', 'AbsoluteDiscountBenefit'])


class PercentageDiscountBenefit(CorePercentageDiscountBenefit):

    def apply(self, basket, condition, offer, discount_amount=None,
              max_total_discount=None):

        print(
            "\n\n\n\n",
            "PRINT SOMETHING",
            "\n\n\n\n",
        )
        return super().apply(basket, condition, offer, discount_amount,
              max_total_discount)


class AbsoluteDiscountBenefit(CoreAbsoluteDiscountBenefit):

    def apply(self, basket, condition, offer, discount_amount=None,
              max_total_discount=None):

        print(
            "\n\n\n\n",
            "PRINT SOMETHING",
            "\n\n\n\n",
        )
        return super().apply(basket, condition, offer, discount_amount,
              max_total_discount)

Error log

RuntimeError at /basket/

Conflicting 'percentagediscountbenefit' models in application 'offer': <class 'oscar.apps.offer.benefits.PercentageDiscountBenefit'> and <class 'oscar_apps.offer.benefits.PercentageDiscountBenefit'>.

Request Method:     GET
Request URL:    http://localhost:8000/basket/
Django Version:     1.11.9
Exception Type:     RuntimeError
Exception Value:    

Conflicting 'percentagediscountbenefit' models in application 'offer': <class 'oscar.apps.offer.benefits.PercentageDiscountBenefit'> and <class 'oscar_apps.offer.benefits.PercentageDiscountBenefit'>.

Exception Location:     /home/seyidov/PycharmProjects/Backend/embahome-backend/.venv/lib/python3.5/site-packages/django/apps/registry.py in register_model, line 224
Python Executable:  /home/seyidov/PycharmProjects/Backend/embahome-backend/.venv/bin/python
Python Version:     3.5.2
Python Path:    

['/home/seyidov/PycharmProjects/Backend/embahome-backend',
 '/home/seyidov/PycharmProjects/Backend/embahome-backend',
 '/usr/lib/python35.zip',
 '/usr/lib/python3.5',
 '/usr/lib/python3.5/plat-x86_64-linux-gnu',
 '/usr/lib/python3.5/lib-dynload',
 '/home/seyidov/PycharmProjects/Backend/embahome-backend/.venv/lib/python3.5/site-packages',
 '/home/seyidov/Documents/Programs/pycharm-2018.2.4/helpers/pycharm_matplotlib_backend',
 '/home/seyidov/PycharmProjects/Backend/embahome-backend']
Shaig Khaligli
  • 4,955
  • 5
  • 22
  • 32
Kanan
  • 23
  • 3

1 Answers1

1

You can't override benefit classes in this way. If you want to create a custom benefit that applies different logic to the core ones, you need to create your own class which is a proxy for the core Benefit model:

from oscar.apps.offer import models

class CustomPercentageDiscountBenefit(models.Benefit):

    class Meta:
        proxy = True

    def apply(self, basket, condition, offer, discount_amount=None, max_total_discount=None):
        # Apply your benefit here

This is explained in more detail in the documentation.

solarissmoke
  • 30,039
  • 14
  • 71
  • 73
  • 1
    Thank you for answer.Also I edited `AbstractBenefit` model. `@property def proxy_map(self): return { self.PERCENTAGE: get_class( 'offer.benefits', 'CustomPercentageDiscountBenefit') }` – Kanan May 27 '19 at 09:10