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')),
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),
]
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.
Related
I am writing basic views and then putting it in urls.py but it is still not working.
views.py
from django.http import HttpResponse
def home(request):
return HttpResponse("hello how are you")
project urls.py
from django.contrib import admin
from django.urls import path,include
urlpatterns = [
path('admin/', admin.site.urls),
path('',include('blog.urls')),
]
blog/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('home/',views.home,name='home')
]
I have also included my app in settings of project (Installed apps).
Some thoughts about that:
Change your urls patterns in your apps urls to:
from .views import *
urlpatterns= [
path('', home,name='home')
]
If its not working send us your installed apps settings and wsgi file
You confused, you need to write http://127.0.0.1:8000/home not only http://127.0.0.1:8000 with your current code.
If you want the view to be rendered in default route so change urls.py as:
from . import views
urlpatterns= [
path('', views.home,name='home')
]
Otherwise, you can only append /home with your current code to work.
for the same code above it is working for the URL http://127.0.0.1:8000/home/
hey i have a url path that i want to lead me to an application url file
but it says page not found
here is my core url:
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('store.urls', namespace='store')),
path('basket/', include('basket.urls', namespace='basket')),
]
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
and here is my basket.url file:
from django.urls import path
from . import views
app_name = 'basket'
urlpatterns = [
path('', views.basket_summary, name='basket_summary'),
]
and this is the view:
from django.shortcuts import render
# Create your views here.
def basket_summary(request):
return render(request, 'store/basket/summary.html')
my app name is basket , and i might add all of the files are defined.
whats the problem ?
You should add a trailing slash after /basket/.
Read more about APPEND_SLASH in the official documentation.
I use django 2.0.7 in my project with django-decorator-include app (version 2.0).
My urls.py:
from django.conf import settings
from django.contrib import admin
from django.urls import path, re_path, include
from django.conf.urls.static import static
from django.conf.urls.i18n import i18n_patterns
from django.contrib.auth.decorators import login_required
from decorator_include import decorator_include
urlpatterns = i18n_patterns(
path('', include('web.urls', namespace='web')),
path('backoffice/', decorator_include([login_required,], 'backoffice.urls', namespace='backoffice')),
) + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
My backoffice.urls:
from django.urls import path, re_path
from django.conf.urls.i18n import i18n_patterns
from django.utils.translation import gettext_lazy as _
from backoffice import views
app_name = 'backoffice'
urlpatterns = (
path('', views.DashboardView.as_view(), name='dashboard'),
)
backoffice is added to INSTALLED_APPS.
In my views (in app web for example) I am able to do reverse URL, for example in my login view I do return redirect('backoffice:dashboard') and it works just perfectly - its redirecting to /backoffice/.
Problem is when I try to do reverse urls in my templates. In one of my templates, when I add code:
<li class="featured">{% trans 'Open dashboard' %}</li>
I get django error:
NoReverseMatch at /
'backoffice' is not a registered namespace
I suppose that problem is related to django-decorator-include, because if I change my include to standard django url include:
path('backoffice/', include('backoffice.urls', namespace='backoffice')),
it works just fine, and I am able to get reverse urls in templates again.
What should I do? Maybe its a bug in django-decorator-include? Any ideas how can I solve that?
I am aware that "Django 2 with router url patterns has changed". I cant manage to work with Router because I am getting an error :
'Specifying a namespace in include() without providing an app_name '
django.core.exceptions.ImproperlyConfigured: Specifying a namespace in include() without providing an app_name is not supported. Set the app_name attribute in the included module, or pass a 2-tuple containing the list of patterns and app_name instead.
I have written a basic model and after that I have created an api folder, I have prepared files "views.py":
from rest_framework import generics
from yogavidya.apps.articles.models import Article
from .serializers import ArticleSerializer
from rest_framework import routers, serializers, viewsets
class ArticleUpdateView(generics.RetrieveUpdateAPIView):
lookup_field = 'pk'
serializer_class = ArticleSerializer
queryset = Article.objects.all()
router = routers.DefaultRouter()
router.register(r'api/articles', ArticleUpdateView, base_name='api-articles')
after I have urls.py :
from django.urls import path, include
from django.conf.urls.i18n import i18n_patterns
from .views import ArticleUpdateView
from django.urls import re_path
urlpatterns = [
re_path(r'articles/(?:page-(?P<page_number>\d+)/)?$', ArticleUpdateView.as_view(), name='article-update'),
]
now I want to add the api to project urls.py
from django.urls import path, include
from django.conf.urls.i18n import i18n_patterns
from django.contrib import admin
from django.contrib.auth import views as auth_views
from django.conf import settings
from django.conf.urls.static import static
from yogavidya.apps.articles import views
from .views import home,home_files, pricing
from rest_framework import routers, serializers, viewsets
urlpatterns += i18n_patterns(
path('admin/', admin.site.urls),
path('articles/', include('yogavidya.apps.articles.urls', namespace="articles")),
)
urlpatterns += [
path('api/articles/', include('yogavidya.apps.articles.api.urls', namespace="api-articles")),
]
How can I set app_name = 'api-articles' as a global variable and manage to import app_name in my urls.py?
I'm trying to learn django by following the book "Django by Example" and probably due to conflicting versions i'm running into this problem when trying to use django.auth together with some URL settings in
settings.py.
Im getting totally frustrated by now since i have no idea how to even begin debugging this error. Any help or advice would be much appreciated
Here's the relevant part of the settings.py file
from django.core.urlresolvers import reverse_lazy
LOGIN_REDIRECT_URL = reverse_lazy('dashboard')
LOGIN_URL = reverse_lazy('login')
LOGOUT_URL = reverse_lazy('logout')
app views.py:
from django.shortcuts import render, redirect
from django.shortcuts import HttpResponse
from django.contrib.auth import authenticate, login, logout
from .forms import LoginForm
from django.contrib.auth.decorators import login_required
# Create your views here.
#login_required
def dashboard(request):
return render(request, 'account/dashboard.html', {'section': 'dashboard'})
urls.py
from django.conf.urls import url
from . import views
app_name = 'account'
urlpatterns = {
url(r'^$', views.dashboard, name='dashboard'),
url(r'^login/$', 'django.contrib.auth.views.login', name='login'),
url(r'^logout/$', 'django.contrib.auth.views.logout', name='logout'),
url(r'^logout-then-login/$', 'django.contrib.auth.views.logout_then_login', name='logout_then_login'),
}
Main urls.py :
from django.conf.urls import url, include
from django.contrib import admin
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^account/', include('account.urls')),
]
Error Message
updated settings.py :
LOGIN_REDIRECT_URL = reverse_lazy('account:dashboard')
LOGIN_URL = reverse_lazy('account:login')
LOGOUT_URL = reverse_lazy('account:logout')
When you use app_name that sets up a namespace that will be used when you include() that urls.py somewhere else.
So there's no url with the name "login", instead it's called "account:login", and that's the name you have to pass to reverse().
LOGIN_REDIRECT_URL = reverse_lazy('account:dashboard')
LOGIN_URL = reverse_lazy('account:login')
LOGOUT_URL = reverse_lazy('account:logout')
Relevant docs: URL namespaces and included URLconfs
If you are using django-extensions (you should), you can use the management command show_urls to get a nicely formatted list of all the url routes that are registered in your project.