newbee
newbee

Reputation: 31

Django-Oscar URLs for Django 2.0?

Django-Oscar has apparently been updated to Django 2.0. I am new to Django, I am not sure how I would update the URLs that are mentioned in the Oscar Tutorial:

from django.conf.urls import include, url
from django.contrib import admin
from oscar.app import application

urlpatterns = [
    url(r'^i18n/', include('django.conf.urls.i18n')),

    # The Django admin is not officially supported; expect breakage.
    # Nonetheless, it's often useful for debugging.
    url(r'^admin/', include(admin.site.urls)),

    url(r'', include(application.urls)),
]

This is the url that is currently available:

urlpatterns = [
    path('admin/', admin.site.urls),
]

So, do this mean that I would change the django-oscar URls to?:

 path(r'^i18n/', include('django.conf.urls.i18n')),

Upvotes: 2

Views: 1004

Answers (2)

Mobasshir Bhuiya
Mobasshir Bhuiya

Reputation: 1092

Django oscar always put their URLs in their app directory's apps.py file and then include that URL's to project level urls.py file, that's the design decision for Django oscar. But I would recommend you use path() than url() as this will help you to avoid the complexity.

##django-oscar/src/oscar/apps/basket/apps.py    
from django.conf.urls import url
from django.contrib.auth.decorators import login_required
from django.utils.translation import gettext_lazy as _

from oscar.core.application import OscarConfig
from oscar.core.loading import get_class


class BasketConfig(OscarConfig):
    label = 'basket'
    name = 'oscar.apps.basket'
    verbose_name = _('Basket')

namespace = 'basket'

def ready(self):
    self.summary_view = get_class('basket.views', 'BasketView')
    self.saved_view = get_class('basket.views', 'SavedView')
    self.add_view = get_class('basket.views', 'BasketAddView')
    self.add_voucher_view = get_class('basket.views', 'VoucherAddView')
    self.remove_voucher_view = get_class('basket.views', 'VoucherRemoveView')

def get_urls(self):
    urls = [
        url(r'^$', self.summary_view.as_view(), name='summary'),
        url(r'^add/(?P<pk>\d+)/$', self.add_view.as_view(), name='add'),
        url(r'^vouchers/add/$', self.add_voucher_view.as_view(),
            name='vouchers-add'),
        url(r'^vouchers/(?P<pk>\d+)/remove/$',
            self.remove_voucher_view.as_view(), name='vouchers-remove'),
        url(r'^saved/$', login_required(self.saved_view.as_view()),
            name='saved'),
    ]
    return self.post_process_urls(urls)

then imported by project level config.py file

##django-oscar/src/oscar/config.py
# flake8: noqa, because URL syntax is more readable with long lines

from django.apps import apps
from django.conf import settings
from django.conf.urls import url
from django.urls import reverse_lazy
from django.views.generic.base import RedirectView

from oscar.core.application import OscarConfig
from oscar.core.loading import get_class


class Shop(OscarConfig):
    name = 'oscar'

    def ready(self):
        from django.contrib.auth.forms import SetPasswordForm

        self.catalogue_app = apps.get_app_config('catalogue')
        self.customer_app = apps.get_app_config('customer')
        self.basket_app = apps.get_app_config('basket')
        self.checkout_app = apps.get_app_config('checkout')
        self.search_app = apps.get_app_config('search')
        self.dashboard_app = apps.get_app_config('dashboard')
        self.offer_app = apps.get_app_config('offer')

        self.password_reset_form = get_class('customer.forms', 'PasswordResetForm')
        self.set_password_form = SetPasswordForm

    def get_urls(self):
        from django.contrib.auth import views as auth_views

        from oscar.views.decorators import login_forbidden

        urls = [
            url(r'^$', RedirectView.as_view(url=reverse_lazy('catalogue:index')), name='home'),
            url(r'^catalogue/', self.catalogue_app.urls),
            url(r'^basket/', self.basket_app.urls),
            url(r'^checkout/', self.checkout_app.urls),
            url(r'^accounts/', self.customer_app.urls),
            url(r'^search/', self.search_app.urls),
            url(r'^dashboard/', self.dashboard_app.urls),
            url(r'^offers/', self.offer_app.urls),

            # Password reset - as we're using Django's default view functions,
            # we can't namespace these urls as that prevents
            # the reverse function from working.
            url(r'^password-reset/$',
                login_forbidden(
                    auth_views.PasswordResetView.as_view(
                        form_class=self.password_reset_form,
                        success_url=reverse_lazy('password-reset-done'),
                        template_name='oscar/registration/password_reset_form.html'
                    )
                ),
                name='password-reset'),
            url(r'^password-reset/done/$',
                login_forbidden(auth_views.PasswordResetDoneView.as_view(
                    template_name='oscar/registration/password_reset_done.html'
                )),
                name='password-reset-done'),
            url(r'^password-reset/confirm/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>.+)/$',
                login_forbidden(
                    auth_views.PasswordResetConfirmView.as_view(
                        form_class=self.set_password_form,
                        success_url=reverse_lazy('password-reset-complete'),
                        template_name='oscar/registration/password_reset_confirm.html'
                    )
                ),
                name='password-reset-confirm'),
            url(r'^password-reset/complete/$',
                login_forbidden(auth_views.PasswordResetCompleteView.as_view(
                    template_name='oscar/registration/password_reset_complete.html'
                )),
                name='password-reset-complete'),
        ]
        return urls

Oscar's idea is to modularize every app. That's why it stores app's all url to apps.py in every app folder and include that to project level config.py file.

Upvotes: 0

solarissmoke
solarissmoke

Reputation: 31404

The documentation on readthedocs is out of date for some reason - here's the most recent version on Github which provides configuration for Django 2.

To use path you need to remove the regular expression syntax in the URLs. The use of include() also has been dropped for url configs passed directly, so you end up with:

from django.urls import include, path
from django.contrib import admin
from oscar.app import application

urlpatterns = [
    path('i18n/', include('django.conf.urls.i18n')),
    path('admin/', admin.site.urls),
    path('', application.urls),
]

Upvotes: 2

Related Questions