How to add views or change URLs or permissions¶
Oscar has many views and associated URLs. Often you want to customise these URLs for your domain, or add additional views to an app.
This how-to describes how to do just that. It builds upon the steps described in Customising Oscar. Please read it first and ensure that you’ve:
- Created a Python module with the the same label
- Added it as Django app to
INSTALLED_APPS
- Added a
models.py
andadmin.py
The application class¶
Each Oscar app comes with an application instance which inherits from
oscar.core.application.Application
. They’re mainly used to gather
URLs (with the correct permissions) for each Oscar app. This structure makes
Oscar apps more modular as each app is responsible for its own URLs. And as
it is a class, it can be overridden like any other Oscar class; hence making
it straightforward to change URLs or add new views.
Each app instance exposes a urls
property, which is used to access the
list of URLs of an app.
The application tree¶
Oscar’s app instances are organised in a tree structure. The root application illustrates this nicely:
# oscar/app.py
class Shop(Application):
name = None
catalogue_app = get_class('catalogue.app', 'application')
basket_app = get_class('basket.app', 'application')
# ...
def get_urls(self):
urls = [
url(r'^catalogue/', include(self.catalogue_app.urls)),
url(r'^basket/', include(self.basket_app.urls)),
# ...
]
The root app pulls in the URLs from its children. That means to add
all Oscar URLs to your Django project, you only need to include the urls
property from the root app:
# urls.py
from oscar.app import application
urlpatterns = [
# Your other URLs
url(r'', include(application.urls)),
]
Changing sub app¶
Sub-apps such as the catalogue
app are loaded dynamically, just as most
other classes in Oscar:
# oscar/app.py
class Shop(Application):
name = None
catalogue_app = get_class('catalogue.app', 'application')
customer_app = get_class('customer.app', 'application')
# ...
That means you just need to create another
application
instance. It will usually inherit from Oscar’s version. Say
you’d want to add another view to the promotions app. You only need to
create a class called PromotionsApplication
(and usually inherit from
Oscar’s version) and add your view:
# yourproject/promotions/app.py
from oscar.apps.promotions.app import PromotionsApplication as CorePromotionsApplication
from .views import MyExtraView
class PromotionsApplication(CorePromotionsApplication):
extra_view = MyExtraView
application = PromotionsApplication()
Changing the root app¶
If you want to e.g. change the URL for the catalogue app from /catalogue
to /catalog
, you need to use a custom root app instance
instead of Oscar’s default instance. Hence, create a subclass of Oscar’s main
Application
class and override the get_urls
method:
# myproject/app.py
from oscar import app
class MyShop(app.Shop):
# Override get_urls method
def get_urls(self):
urlpatterns = [
url(r'^catalog/', include(self.catalogue_app.urls)),
# all the remaining URLs, removed for simplicity
# ...
]
return urlpatterns
application = MyShop()
As the root app is hardcoded in your project’s urls.py
, you need to modify
it to use your new application instance instead of Oscar’s default:
# urls.py
from myproject.app import application
urlpatterns = [
# Your other URLs
url(r'', include(application.urls)),
]
All URLs containing catalogue
previously are now displayed as catalog
.