Skip to main content
 首页 » 编程设计

python之如何在 django oscar 的策略中应用可变税

2024年09月03日27EasonJim

我正在为印度开展一个奥斯卡项目,现在我想对产品征税。 我已按照文档对 prices and availability 征税。 , fork 合作伙伴应用程序。当我指定 rate=('0.20') 时,它对所有产品征收 20% 的税,现在我想让它动态化。

所以我查看了 strategy.FixedRateTax 的代码,并尝试实现 get_rate() 的代码,因为所有产品都会调用它。

我想让它变得动态的方式是,根据我想对 get_rate() 中的产品征税的产品类别。

所以我在 core/models.py 中创建了一个模型

class CategoryTax(models.Model): 
    category = models.OneToOneField(Category, on_delete=models.CASCADE, unique=True) 
    gst_tax = models.DecimalField(max_digits=11, decimal_places=4, null=True, default=0) 
 
    def __str__(self): 
        return "%s" % self.category 

这里导入类别模型工作正常,但是当我转到 strategy.py 并从核心和其他应用程序导入模型时,django 出现异常。

我的 forked_apps/partner/strategy.py 是:

from decimal import Decimal as D 
from oscar.apps.partner import strategy, prices 
from django.conf import settings 
 
from oscar.core.loading import get_model 
from core.models import CategoryTax 
 
Partner = get_model('partner', 'Partner') 
Category = get_model('catalogue', 'Category') 
Product = get_model('catalogue', 'Product') 
ProductCategory = get_model('catalogue', 'ProductCategory') 
 
 
class Selector(object): 
    """ 
    Custom selector to return a India-specific strategy that charges GST 
    """ 
 
    def strategy(self, request=None, user=None, **kwargs): 
        return IndiaStrategy() 
 
 
class IncludingVAT(strategy.FixedRateTax): 
    """ 
    Price policy to charge VAT on the base price 
    """ 
    # We can simply override the tax rate on the core FixedRateTax.  Note 
    # this is a simplification: in reality, you might want to store tax 
    # rates and the date ranges they apply in a database table.  Your 
    # pricing policy could simply look up the appropriate rate. 
 
    # The Tax rate applied here is 3 % GST Now 
    rate = D(settings.SITE_GST) 
 
    def get_rate(self, product, stockrecord): 
        """ 
        This method serves as hook to be able to plug in support for varying tax rates 
        based on the product. 
 
        TODO: Needs tests. 
        """ 
 
        try: 
            product = Product.objects.get(id=product.id) 
            prod_cat = ProductCategory.objects.get(product=product) 
            cat = Category.objects.get(id=prod_cat.category_id) 
 
            cat_tax = CategoryTax.objects.get(category=cat) 
            print("The Cat Tax: ", cat_tax) 
 
        except Exception as e: 
            print(e) 
        return self.rate 
class IndiaStrategy(strategy.UseFirstStockRecord, IncludingVAT, 
             strategy.StockRequired, strategy.Structured): 
    """ 
    Typical India strategy for physical goods. 
 
    - There's only one warehouse/partner so we use the first and only stockrecord 
    - Enforce stock level.  Don't allow purchases when we don't have stock. 
    - Charge Indian GST on prices.  Assume everything is standard-rated. 
    """ 

我得到的异常是:

django.core.exceptions.AppRegistryNotReady: Models aren't loaded yet. 

还有:ImportError: cannot import name 'CategoryTax'

请给我建议我可以用来完成这项工作的任何方法。

我正在使用 Django 2.1.3、Django Oscar 1.6.4

整个错误堆栈跟踪:

Unhandled exception in thread started by <function check_errors.<locals>.wrapper at 0x7f623e655400> 
Traceback (most recent call last): 
  File "/home/venvs/test/lib/python3.6/site-packages/oscar/core/loading.py", line 296, in get_model 
    return apps.get_model(app_label, model_name) 
  File "/home/venvs/test/lib/python3.6/site-packages/django/apps/registry.py", line 195, in get_model 
    self.check_models_ready() 
  File "/home/venvs/test/lib/python3.6/site-packages/django/apps/registry.py", line 137, in check_models_ready 
    raise AppRegistryNotReady("Models aren't loaded yet.") 
django.core.exceptions.AppRegistryNotReady: Models aren't loaded yet. 
 
During handling of the above exception, another exception occurred: 
 
Traceback (most recent call last): 
  File "/home/venvs/test/lib/python3.6/site-packages/oscar/core/loading.py", line 296, in get_model 
    return apps.get_model(app_label, model_name) 
  File "/home/venvs/test/lib/python3.6/site-packages/django/apps/registry.py", line 195, in get_model 
    self.check_models_ready() 
  File "/home/venvs/test/lib/python3.6/site-packages/django/apps/registry.py", line 137, in check_models_ready 
    raise AppRegistryNotReady("Models aren't loaded yet.") 
django.core.exceptions.AppRegistryNotReady: Models aren't loaded yet. 
 
During handling of the above exception, another exception occurred: 
 
Traceback (most recent call last): 
  File "/home/venvs/test/lib/python3.6/site-packages/django/utils/autoreload.py", line 225, in wrapper 
    fn(*args, **kwargs) 
  File "/home/test/abhushan/lib/python3.6/site-packages/django/core/management/commands/runserver.py", line 109, in inner_run 
    autoreload.raise_last_exception() 
  File "/home/venvs/test/lib/python3.6/site-packages/django/utils/autoreload.py", line 248, in raise_last_exception 
    raise _exception[1] 
  File "/home/venvs/test/lib/python3.6/site-packages/django/core/management/__init__.py", line 337, in execute 
    autoreload.check_errors(django.setup)() 
  File "/home/venvs/test/lib/python3.6/site-packages/django/utils/autoreload.py", line 225, in wrapper 
    fn(*args, **kwargs) 
  File "/home/venvs/test/lib/python3.6/site-packages/django/__init__.py", line 24, in setup 
    apps.populate(settings.INSTALLED_APPS) 
  File "/home/venvs/test/lib/python3.6/site-packages/django/apps/registry.py", line 112, in populate 
    app_config.import_models() 
  File "/home/venvs/test/lib/python3.6/site-packages/django/apps/config.py", line 198, in import_models 
    self.models_module = import_module(models_module_name) 
  File "/home/venvs/test/lib/python3.6/importlib/__init__.py", line 126, in import_module 
    return _bootstrap._gcd_import(name[level:], package, level) 
  File "<frozen importlib._bootstrap>", line 994, in _gcd_import 
  File "<frozen importlib._bootstrap>", line 971, in _find_and_load 
  File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked 
  File "<frozen importlib._bootstrap>", line 665, in _load_unlocked 
  File "<frozen importlib._bootstrap_external>", line 678, in exec_module 
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed 
  File "/home/venvs/test/project/core/models.py", line 8, in <module> 
    Category = get_model('catalogue', 'Category') 
  File "/home/venvs/test/lib/python3.6/site-packages/oscar/core/loading.py", line 308, in get_model 
    import_module('%s.%s' % (app_config.name, MODELS_MODULE_NAME)) 
  File "/home/venvs/test/lib/python3.6/importlib/__init__.py", line 126, in import_module 
    return _bootstrap._gcd_import(name[level:], package, level) 
  File "<frozen importlib._bootstrap>", line 994, in _gcd_import 
  File "<frozen importlib._bootstrap>", line 971, in _find_and_load 
  File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked 
  File "<frozen importlib._bootstrap>", line 665, in _load_unlocked 
  File "<frozen importlib._bootstrap_external>", line 678, in exec_module 
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed 
  File "/home/venvs/test/lib/python3.6/site-packages/oscar/apps/catalogue/models.py", line 4, in <module> 
    from oscar.apps.catalogue.abstract_models import *  # noqa 
  File "/home/venvs/test/lib/python3.6/site-packages/oscar/apps/catalogue/abstract_models.py", line 35, in <module> 
    Selector = get_class('partner.strategy', 'Selector') 
  File "/home/venvs/test/lib/python3.6/site-packages/oscar/core/loading.py", line 59, in get_class 
    return get_classes(module_label, [classname], module_prefix)[0] 
  File "/home/venvs/test/lib/python3.6/site-packages/oscar/core/loading.py", line 69, in get_classes 
    return class_loader(module_label, classnames, module_prefix) 
  File "/home/venvs/test/lib/python3.6/site-packages/oscar/core/loading.py", line 141, in default_class_loader 
    local_module = _import_module(local_module_label, classnames) 
  File "/home/venvs/test/lib/python3.6/site-packages/oscar/core/loading.py", line 182, in _import_module 
    return __import__(module_label, fromlist=classnames) 
  File "/home/test/forked_apps/partner/strategy.py", line 16, in <module> 
    Category = get_model('catalogue', 'Category') 
  File "/home/venvs/test/lib/python3.6/site-packages/oscar/core/loading.py", line 311, in get_model 
    return apps.get_registered_model(app_label, model_name) 
  File "/home/venvs/test/lib/python3.6/site-packages/django/apps/registry.py", line 270, in get_registered_model 
    "Model '%s.%s' not registered." % (app_label, model_name)) 
LookupError: Model 'catalogue.Category' not registered. 

请您参考如下方法:

您的循环导入导致失败。在 strategy.py 中,您试图加载 Category 模型,而在 Oscar 的 catalogue/abstract_models.py 中,它又试图加载Selector 模型(出于我不清楚的原因 - 认为这实际上是一个错误,将单独研究它)。

我认为如果您将 selector.py 中的导入移动到需要它们的方法内部,它应该可以工作:

def get_rate(self, product, stockrecord): 
    Category = get_model('catalogue', 'Category') 
    Product = get_model('catalogue', 'Product') 
    ProductCategory = get_model('catalogue', 'ProductCategory') 
    # do your logic here