Django url patterns for different currencies - django

I am building a site in english and simply want to offer a small subset of currencies. For SEO and caching I am planning to develop the following url structure with the prices being displayed in the relevant currencies.
Home(s)
site.com/
site.com/au/
site.com/us/
...
Categories Index Pages
site.com/categories/
site.com/au/categories/
site.com/us/categories/
...
Product Index Pages
site.com/categories/category1/
site.com/au/categories/category1/
site.com/us/categories/category1/
...
Product Pages
site.com/categories/category1/product-1/
site.com/au/categories/category1/product-1/
site.com/us/categories/category1/product-1/
...
This is my attempted url.py
urlpatterns = patterns('',
#url(r'^$', views.homeCurrency, {'cur_slug': '' }, name='home'),
url(r'^(?P<cur_slug>[:au|nz|us|eu|ca|uk]+)/$', views.homeCurrency, name='home'),
url(r'^categories/', include('parts.urls', namespace="parts")),
url(r'^(?P<cur_slug>[:au|nz|us|eu|ca|uk]+)/bike-parts/', include('parts.urls', namespace="parts")),
)
This is the sort of dynamic url I need in my base.html
Home
My problem is two fold (I think)
Firstly, I can't allow for the default case i.e. site.com(/) in the url pattern so that there is a common url name that can be used dynamically throughout each version of the site.
Secondly, even ignoring the default case, I am getting the following error:
Request Method: GET
Request URL: site.com/au/
Django Version: 1.5.4
Exception Type: NoReverseMatch
Exception Value:
Reverse for 'home' with arguments '()' and keyword arguments '{}' not found.
Any help would be greatly appreciated as this is my first project in Django. Cheers

The first problem is with your regex. [] means character class, i.e. [a|bc] would match a, |, b or c but never bc.
Hence, your regex should be using groups ():
url(r'^(?P<cur_slug>au|nz|us|eu|ca|uk)/$', views.homeCurrency, name='home'),
If you're not 100% confident with regex, you should have a look into the excellent surlex library, which provides a neat little DSL for writing URL patterns.
from surlex.dj import surl
// a macro for valid currencies
surlex.register_macro('$', r'au|nz|us|eu|ca|uk')
urlpatterns = patterns('',
// macros are only used in match groups (surrounded with `<>`)
surl(r'<cur_slug:$>/$', views.homeCurrency, name='home'),
surl(r'<cur_slug:$>/bike-parts/$', include('parts.urls', namespace="parts")),
)
regarding your choice of "dynamic url", why not instead base your url roots on locale, and choose the correct currency based on locale. REF

Related

A 404 error if slug begins with “id-” on multilingual website with Indonesian language in Django 3.0

http://example.com/de/id-button/ - 200 OK
http://example.com/id/id-button/ - 200 OK
http://example.com/any-other-slug/ - 200 OK
http://example.com/id-button/ - 404 error:
Using the URLconf defined in example.urls, Django tried these URL patterns, in this order:
id/
The current path, id-button/, didn't match any of these.
urls.py file:
urlpatterns = i18n_patterns(
path('admin/', admin.site.urls),
path('', cache_page(cache_homepage)(homepage_views.index), name='index'),
path('search/', search_views.search, name='search'),
path('<slug:slug>/', item_views.item, name='item'),
prefix_default_language=False,
)
The item have a slug field in DB "id-button".
If I rename this to "idbutton":
http://example.com/idbutton/ - 200 OK
But I need to have url like: http://example.com/id-button/
Update:
It's accepted as a bug, but it's not moving for now:
https://code.djangoproject.com/ticket/31540
This is due to an interaction between LocaleMiddleware and i18n_patterns.
When LocaleMiddleware sees the request coming in, it tries to parse the language from the request. See https://github.com/django/django/blob/92507bf3ea4dc467f68edf81a686548fac7ff0e9/django/utils/translation/trans_real.py#L46 for the regular expression used. The allowed format is: any sequence of word characters, and optionally a dash and more word characters, after that it expects either the end of the string, or a /. In this case, it matches id-domain/, and understands that id-domain is the language prefix for that request, causing Django to activate the id language.
Then, the request goes through the URL routing layer, reaching as one of the first stops the https://github.com/django/django/blob/master/django/urls/resolvers.py#L301 . The get_language() command returns id, and the prefix thus searched for is id/, which id-domain/ does not match against. As the LocalePrefixPattern is the top-level resolver, it not matching causes nothing else to be tried.
(Is it a bug in Django? Maybe, I'd expect it seeing id-domain/ as language would make it also be used for language-prefix for the URL resolving. But even then it might not resolve your problem)

What is the ideal format/structure of urlconfs in django 2

I creating an application and one of its urlconf is as follows
urlpatterns = [
path('', DashboardView.as_view(),name='dashboard:index'),
]
I am coming from PHP background (say Laravel) where we name our routes like below
dashboard:index - for get
dashboard:store - for post
dashboard:update - for patch etc...
So I named my route as above, but while performing the system check, the following warning comes up.
System check identified some issues:
WARNINGS: ?: (urls.W003) Your URL pattern '' [name='dashboard:index']
has a name including a ':'. Remove the colon, to avoid ambiguous
namespace references.
System check identified 1 issue (0 silenced).
So my question is what is the ideal naming format of URLs in Django in general.
dashboard_index ?
dashboard.index ?
I guess the best place to find some kind of convention is in the django admin app, where I found this:
urlpatterns = [
url(r'^$',
views.BaseAdminDocsView.as_view(template_name='admin_doc/index.html'),
name='django-admindocs-docroot'),
url(r'^bookmarklets/$',
views.BookmarkletsView.as_view(),
name='django-admindocs-bookmarklets'),
# and so on...
]
So, a string representing the url with dashes between words. I think is also important the name to be very explicit, not acronyms or shortened names.
EDIT:
Example of general url/path naming from the docs (2.1):
path('archive/', views.archive, name='news-archive')
Also it's a good idea to have in mind python code style.

How can I use a catch all route using `path` or `re_path` so that Django passes all unmatched requests to my index view?

My url patterns look like this:
urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include('api.urls')),
re_path('.*', IndexView.as_view()),
]
This works but it matches all URLs, including those prefixed with admin and api. I want those URLs to still match, and for any unmatched URLs to render IndexView.
Before 2.0 I used this regex for this purpose. I tried using it in re_path but that didn't work, which is what led me to trying the above.
url(r'^(?P<path>.*)/$', HtmlView.as_view())
Use case is a SPA where I handle 404s client side.
Many thanks in advance.
You can use two entries (one for '/', another one for anything else), but using path for both of them, which should be (slightly) more efficient:
urlpatterns = [
path('', IndexView.as_view(), {'resource': ''}),
path('<path:resource>', IndexView.as_view())
]
In this case, I'm using <path:resource> because path catches all resource names, inluding that with / in them. But it does not capture the main index resource, /. That's why the first entry. The dictionary as last argument for it is because we need to provide a resource parameter if we want to use the same view than in the second entry.
That view, of course, should have 'resource' as a paremeter:
def as_view(request, resource):
...
So as I said in the question description, trying the regex I was using before Django 2.0 in re_path did not work. It would basically match for all requests except / (i.e., index path). I fixed this by using both that regex and a second path matching / specifically. Here's the code:
urlpatterns = [
re_path(r'^(?P<path>.*)/$', IndexView.as_view()),
path('', IndexView.as_view()),
]
With these changes my other routes would match and these two routes would account for all other urls.
One Idea to go about this is let the django catch 404.
url.py
from django.conf.urls import handler404
handler404 = 'app_name.views.bad_request'
and in your views.py
views.py
def bad_request(request):
return redirect(reverse('home'))
You can always do some regex thingy to catch unmatched urls. but hey this gets the job done. :)

How to go to a different page from current in Django template

urlpatterns = [
url(r'^$', predict_views.index, name = 'HomePage'),
url(r'^admin/', admin.site.urls),
url(r'^Update_db/$', predict_views.Update_db, name = 'Update_db'),
url(r'^compare/(?P<phone1_id>[0-9]+)/(?P<phone2_id>[0-9]+)/$',predict_views.Compare, name = 'Compare'),
url(r'^predict/(?P<phone_id>[0-9]+)/$',predict_views.Predict, name = 'Predict'),
]
these are my url patterns in djano. I want to go to compare directly from predict which is not possible for me currently because :
when I go to predict the url is 127.0.0.1:8000/predict/1 now when i go to compare from predict the url becomes 127.0.0.1:8000/predict/1/compare/1/2 which is not the expected url .. my url should be 127.0.0.1:8000/compare/1/2
I have seen django docs there are some redirect methods but I do not understand them.
Any help is appreciated.
Something tells me you are accidentally using relative urls. In your template, try the following:
Compare Page

Django error with (CRUD) urls.py

as part of my continuing want to do well on my Uni course, I'm doing a bit of web-dev in Python(2.7) using Django. I had followed Django's tutorial and now I am following this tutorial. However, I get a somewhat inexplicable error when I add in the urls.py part to give me some viewing models. The project is called 'practice' and the app is called 'orders'. Within 'orders' are the models (which all validate)
The (relevant part of) urls.py is:
'django.views.generic.list_details',
url(r'^orders/$', 'object_list', {'queryset': 'orders.Product.objects.all()'}),
url(r'^orders(?P<slug>[-\W]+)/$', 'object_detail', {'queryset': 'orders.Product.objects.all()'})
I've double checked ROOT_URLCONF is correctly set so the error appears to be somewhere within 'django.views.generic.list_details' as a use.
The error message is:
AttributeError: 'str' object has no attribute resolve
A good Google didn't seem to produce anything reasonable so any chance of a hand please guys?
Thanks!
Did you forget "patterns"?
urlpatterns = patterns('',
(r'^$', ...),
# ...
Also I've noticed a slash missing:
url(r'^orders(?P<slug>[-\W]+)/$', 'object_detail', {'queryset': 'orders.Product.objects.all()'})
url(r'^orders/(?P<slug>[-\W]+)/$', 'object_detail', {'queryset': 'orders.Product.objects.all()'})
The AttributeError suggests to me that the string 'django.views.generic.list_details' is being treated as a url to be resolved. However, you've omitted too much of your urls.py to say for sure.
Make sure the prefix string is the first argument to django.conf.urls.patterns. If you want to break up your urls and use different prefix strings, invoke patterns multiple times as described in the documentation:
urlpatterns = patterns('myapp.views',
url(r'^$', 'app_index'),
url(r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/$','month_display'),
)
urlpatterns += patterns('weblog.views',
url(r'^tag/(?P<tag>\w+)/$', 'tag'),
)
You've quoted the value in the arguments dictionary in each pattern, so it's being treated as a string. It should be:
url(r'^orders/$', 'object_list', {'queryset': orders.Product.objects.all()})
Not that you'll need to import orders - except I doubt that will work, because Product will be defined in the models file inside orders. It would be easier to just import Product and refer to it directly.