set a parameter with default value to route url in django - django

Hy all!
I'm new to python / django and I came across a problem that I can not solve. I have a route configured for the site's home (1) and a route configured for categories (2):
1) url(r'^$', IndexView().home, name='home')
2) url(r'^categoria/(?P<path>.*)/$', IndexView().by_category, name='by_category')
I need to set my home url to open a category by default, something like www.mysite.com/c=defaul_category
I tried in some ways, including: url (r '^ / (? P \ w +) / $', IndexView (). Home, name = 'home'). But I know it's incorrect.
So... I have no idea how to do this. Could someone help me?
Thank you

You should tell django that path in by_category url may be omitted. You have at least two options here:
1 - create one more url without path but with passed path variable as 3-rd argument in url:
url(r'^/(?P<c=vinhos>\w+)/$', IndexView().home, name='home')
url(r'^categoria/(?P<path>.*)/$', IndexView().by_category, name='by_category')
url(r'^categoria/$', IndexView().by_category,
{'path': 'default_path'}, name='default_category')
2 - change regex pattern to make it possible to omit path parameter. Here | (or sign) added in the end of path group:
url(r'^categoria/(?P<path>.*|)/$', IndexView().by_category, name='by_category')
More about omitting url parameters Django optional url parameters

Related

301 redirect router for Django project

I have a website building tool created in Django and I'd like to add easy user defined 301 redirects to it.
Webflow has a very easy to understand tool for 301 redirects. You add a path (not just a slug) and then define where that path should lead the user.
I'd like to do the same for the Django project I'm working on. I currently allow users to set a slug that redirects /<slug:redirect_slug>/ and they can set to go to any URL. But I'd like them to be able to add, for example, the path for an old blog post '/2018/04/12/my-favorite-thing/'
What's the best URL conf to use in Django to safely accept any path the user wants?
You can use the Path Converters that convert the path parameters into appropriate types, which also includes a converter for urls.
An example would be like the following:
path('api/<path:encoded_url>/', YourView.as_view()),
As per the docs:
Matches any non-empty string, including the path separator, '/'. This allows you to match against a complete URL path rather than just a segment of a URL path as with str.
In your view, you can get your URL like this:
encoded_url = self.kwargs.get('encoded_url')
Add a RerouteMiddleware which first checks if the request can be served by the existing URLs from the urls.py. If it cannot be served, check if the requested path is from the old -> new URLs mapping, if a match found redirect it to the new URL.
Sample piece of code to try it out.
try:
resolve(request.path_info)
except Resolver404:
# Check if the URL exists in your database/constants
# where you might have stored the old -> new URL mapping.
if request.path is valid:
new_url = # Retrieve the new URL
return redirect(new_url)
response = self.get_response(request)
return response

How to pass # in url as a parameter in django 2

I am trying to pass a code "Req-2019#000001" Django URL. I want to pass this code as well as normal string and number also in URL as arguments.
path('generateBomForSingleProduct/<requisition_no>/' , views.generateBomForSingleProduct, name='generateBomForSingleProduct'),
Its work properly but the problem is its add extra / before #
My URL is now this
http://127.0.0.1:8000/production/generateBomForSingleProduct/Req-2019/#000001
But I want to like this
http://127.0.0.1:8000/production/generateBomForSingleProduct/Req-2019#000001
Not an extra "/" before my "#"
The portion of the URL which follows the # symbol is not normally sent to the server in the request for the page. So, it's not possible to have a URL as /production/generateBomForSingleProduct/Req-2019#000001
Workaround
Just modify the url as /production/generateBomForSingleProduct/Req-2019/000001, so you need to modify the view also
# views.py
def generateBomForSingleProduct(request, part_1, part_2):
unique_id = "{}#{}".format(part_1, part_2)
# use the "unique_id"
...
#urls.py
urlpatterns = [
...,
path('foo/<part_1>/<part_2>/', generateBomForSingleProduct, name="some-name"),
...
]
Using 'get' would be the proper way to do this. # is for html fragments, which are not sent to the server. Why can't it just be
/production/generateBomForSingleProduct/Req-2019?code=000001 and then you handle everything in the view that way?
Part after # is called fragment identifier, which is used by browsers and never sent to server.
In http://127.0.0.1:8000/production/generateBomForSingleProduct/Req-2019/#000001 url 000001 is never sent to server. Hence using important part of url after # is useless. Better to pass 000001 as query parameters or separate argument.

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.

Django url patterns for different currencies

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

Django: Permanent redirect of URL with regex parameters

I've been looking all over and can't find what I'm looking for.
I've found a way to redirect urls without parameters and keywords - but how to do it with parameters?
I want to redirect this:
(r'^andelsboligforeninger/(?P<page>[\d]*?)/$', 'cooperatives'),
to this:
(r'^liste-over-andelsboligforeninger/(?P<page>[\d]*?)/$', 'cooperatives'),
It should be a permanent redirect. This will be good for the SEO, and I get so many debug mails because of googlebot.
It seems I've found my answer in the django docs - I didn't look hard enought after all!
https://docs.djangoproject.com/en/1.1/ref/generic-views/
urlpatterns = patterns('django.views.generic.simple',
('^foo/(?P<id>\d+)/$', 'redirect_to', {'url': '/bar/%(id)s/'}),
)
First of all you need to do some changes in the url. Use url function and then give a name to the url. You have some issues in your url, for example you have used ?P but did'nt give a name to the capturing group. Second [\d]*? there is no need for ? because * means there can be a digit or not at all. So after considering all the above mentioned bugs and techniques in the end your url should look like this:
url(r'^liste-over-andelsboligforeninger/(?P<cooperative_id>\d*)/$', 'cooperatives', name="cooperatives")
Then in the view you can use reverse url resolution as:
redirect(reverse('cooperatives', kwargs={'cooperative_id': some_id}))