Search code examples
djangodjango-modelsdjango-oscar

how to import models to oscar.partner app's strategy module correctly?


I have defined declared my own Strategy to Select a Stock and a price as described in http://django-oscar.readthedocs.io/en/releases-1.1/topics/prices_and_availability.html

Everything worked fine until I had the need to import a custom model class that I created in the catalogue app. My goal was to access this custom model for the price selection strategy.

in /apps/partner/strategy I tried to import the model like this:

CountrySpecificProductInformation = get_model('catalogue', 'CountrySpecificProductInformation')

this call raises a Model not Registered exception:

  File "/home/matyas/virtenvs/oscar/local/lib/python2.7/site-packages/oscar/core/loading.py", line 250, in get_model
    return apps.get_registered_model(app_label, model_name)
  File "/home/matyas/virtenvs/oscar/local/lib/python2.7/site-packages/django/apps/registry.py", line 260, in get_registered_model
    "Model '%s.%s' not registered." % (app_label, model_name))
LookupError: Model 'catalogue.CountrySpecificProductInformation' not registered.

my Installed apps settings look like this:

INSTALLED_APPS = ['...'] +
 oscar.get_core_apps(['apps.catalogue', 'apps.promotions', 'apps.dashboard',
                             'apps.dashboard.catalogue', 'apps.partner', 'apps.payment', 'apps.dashboard.partners',
                             'apps.shipping', 'apps.checkout', 'apps.search'])

I am using django-oscar 1.3 with Django 1.9.9


Solution

  • Oscar has its own importing, system that is necessary to be able to overwrite any part of any app of the e-commerce solution.

    The strategy class gets imported early on the when the server starts, and some models are not registered at that time yet.

    The solution was to import the module not at the top of the module in the import section, but instaed only in the method where the models are necessary. (In my case that was the the select_stockrecord method:

    from oscar.core.loading import get_class, get_model
    CountrySpecificProductInformation = get_model('catalogue', 'CountrySpecificProductInformation')

    def select_stockrecord(self, product):
        CountrySpecificProductInformation = get_model('catalogue', 'CountrySpecificProductInformation')
        Country = get_model('catalogue', 'Country')
    

    It is not a perfect solution but I prefer this rather than writing raw sql queries directly to the database.