Django 2+ : Optional URL using PATH, without making multiple URL - python

i have this url
path('<slug>/thank_you/<user_id>', thank_you, name='thank_you'),
i want the <user_id> to be optional, but i dont want to make 2 urls like this
path('<slug>/thank_you', thank_you, name='thank_you'),
path('<slug>/thank_you/<user_id>', thank_you, name='thank_you2'),
i understand that you can make it optional using regex, but thats if you're using django <2 (using url, not path)
how do i obtain this ?

You can use URL Query String for this. For example:
# URL
path('/thank_you/', thank_you, name='thank_you'),
# View
def thank_you(request, slug):
user_id = request.GET.get('from')
# rest of the code
# Example route
http://localhost:8000/dummy-slug/thank_you/?from=dummy_user_id

Related

Wagtail render any path in index page

I need to enable some pages to write an arbitrary URL that does not depend on the structure of the site.
For example I have structure:
/
/blog
/blog/blogpost1
/blog/blogpost2
But, for example, I need change url from /blog/blbogpost2 to /some/blogpost/url1
For this, I decided to give the opportunity to handle any URL of the main page of the site.
class IndexPage(RoutablePageMixin, Page):
...
#route(r'^(?P<path>.*)/$')
def render_page_with_special_path(self, request, path, *args, **kwargs):
pages = Page.objects.not_exact_type(IndexPage).specific()
for page in pages:
if hasattr(page, 'full_path'):
if page.full_path == path:
return page.serve(request)
# some logic
But now, if this path is not found, but I need to return this request to the standard handler. How can I do it?
This isn't possible with RoutablePageMixin; Wagtail treats URL routing and page serving as two distinct steps, and once it's identified the function responsible for serving the page (which, for RoutablePageMixin, is done by checking the URL route given in #route), there's no way to go back to the URL routing step.
However, it can be done by overriding the page's route() method, which is the low-level mechanism used by RoutablePageMixin. Your version would look something like this:
from wagtail.core.url_routing import RouteResult
class IndexPage(Page):
def route(self, request, path_components):
# reconstruct the original URL path from the list of path components
path = '/'
if path_components:
path += '/'.join(path_components) + '/'
pages = Page.objects.not_exact_type(IndexPage).specific()
for page in pages:
if hasattr(page, 'full_path'):
if page.full_path == path:
return RouteResult(page)
# no match found, so revert to the default routing mechanism
return super().route(request, path_components)

django ignore slash in url and take parameter

hi i have url like this:
path('api/v1/store/download/<str:ix>/', DownloadVideoAPI.as_view(), name='download'),
it accept long string .
I want to keep allthing after download key in above URL as the parameter.
but when I enter a long string that contains some slash Django says page not found for example when if enter "/api/v1/store/download/asdasd2asdsadas/asdasd" will give me 404 not found ...
how can I do that?
this is my view:
class DownloadVideoAPI(APIView):
def get(self, request, ix):
pre = ix.split(",")
hash = pre[0]
dec = pre[1]
de_hash = decode_data(hash, dec)
Well, It's possible to add the extra parameters in the request. you can use re_path method.
# urls.py
from django.urls import re_path
re_path(r'api/v1/store/download/(?P<ix>\w+)/', DownloadVideoAPI.as_view(), name='download'),
ref: https://docs.djangoproject.com/en/2.0/ref/urls/#django.urls.re_path
Just use
path('api/v1/store/download/<str:ix>', DownloadVideoAPI.as_view(), name='download'),
without / at the end.
/api/v1/store/download/asdasd2asdsadas/asdasd will result in a 404 page since Django cannot map the URL, /api/v1/store/download/asdasd2asdsadas/, to a route in your urls.py. To solve this, aside from using BugHunter's answer, you could URL encode your long string first before passing it to your URL.
So, given the long string, "asdasd2asdsadas/asdasd", URL encode it first to "asdasd2asdsadas%2Fasdasd". Once you have encoded it, your URL should now look like "/api/v1/store/download/asdasd2asdsadas%2Fasdasd".
To URL encode in Python 3, you can use urllib.
import urllib
parameter = 'asdasd2asdsadas/asdasd'
encoded_string = urllib.quote(parameter, safe='')
encoded_string here should have the value, "asdasd2asdsadas%2Fasdasd".

How this Odoo website route will work

I am learning website module of Odoo 9 and want to know the format of route expression. I am aware about the regex but could not get it completely. Take a look to this :-
class WebsiteBlog(http.Controller):
_blog_post_per_page = 20
_post_comment_per_page = 10
# codes
#http.route([
'/blog/<model("blog.blog"):blog>',
'/blog/<model("blog.blog"):blog>/page/<int:page>',
'/blog/<model("blog.blog"):blog>/tag/<string:tag>',
'/blog/<model("blog.blog"):blog>/tag/<string:tag>/page/<int:page>',
], type='http', auth="public", website=True)
def blog(self, blog=None, tag=None, page=1, **opt):
print 123
# etc
You can find this code on Git: Website Blog Module
I want to understand these expression. I can understand that this function will be executed if any one of these four URL will be requested by the browser and blog, tag and page are the variables but what is the meaning of this model(blog.blog) here ?
It defines that you are passing a value in URL is the record of the model blog.blog.
Ex.
your url like this..
localhost:8069/blog/3
Then in the controller you will get the record of model blog.blog which is having id = 3.

Python - Django URLField

I have a Django project which contains models with URLField. For the same project, I am writing non-Django Python script, and would like to normalise urls.
url1 = //habrastorage.org/files/fa9/f33/091/fa9f330913c0462c8f576393f4135ec6.jpg
url2 = http://habrastorage.org/files/fa9/f33/091/fa9f330913c0462c8f576393f4135ec6.jpg
url3 = www.habrastorage.org/files/fa9/f33/091/fa9f330913c0462c8f576393f4135ec6.jpg
How can I normalise the urls? Is it possible to cast a url to an instance of Django's URLField? Ideally, I would prefer if all urls would be in the same format as url2.
Thanks!
I'm not sure what you want to achieve but to normalize your urls to look like the second one you could just use a regular expression and do a substitution with the regex module.
formatted_url = re.sub(r'^((http\:|)//|www\.)?(?P<url>.*)', r'http://\g<url>', your_url)
That would take any url of the form //blabla.com, www.blabla.com and http://blabla.com and return http://blabla.com
Here's an example of how it could be used
import re
def getNormalized(url):
"""Returns the normalized version of a url"""
return re.sub(r'^((http\:|)//|www\.)?(?P<url>.*)',
r'http://\g<url>',url)
url1 = '//habrastorage.org/files/fa9/f33/091/fa9f330913c0462c8f576393f4135ec6.jpg'
url2 = 'http://habrastorage.org/files/fa9/f33/091/fa9f330913c0462c8f576393f4135ec6.jpg'
url3 = 'www.habrastorage.org/files/fa9/f33/091/fa9f330913c0462c8f576393f4135ec6.jpg'
formatted_url1 = getNormalized(url1)
formatted_url2 = getNormalized(url2)
formatted_url3 = getNormalized(url3)
print(formatted_url1)
# http://habrastorage.org/files/fa9/f33/091/fa9f330913c0462c8f576393f4135ec6.jpg
print(formatted_url2)
# http://habrastorage.org/files/fa9/f33/091/fa9f330913c0462c8f576393f4135ec6.jpg
print(formatted_url3)
# http://habrastorage.org/files/fa9/f33/091/fa9f330913c0462c8f576393f4135ec6.jpg
If you want to know how it's done check the code. Here you will find the to_python function that formats the return string.
https://github.com/django/django/blob/master/django/forms/fields.py#L705-L738
It uses urlparse or rather django's own copy for python2 and 3 support.

Assigning URL String to Variable in Django

From what I can see there are 2 ways of using a string from within the URL. Either by using the URLConf or via request.GET.get.
Im trying to use the request.GET.get method and trying to capture the string after the = sign on a URL such as www.domain.co.uk/macoui=001100
URLConf
url(r'^macoui=\d{6}$', 'domain.views.output'),
View
def output(request):
if request.method == 'GET':
request.GET.get('macoui', '')
return render_to_response('template.html', {'response': '\'%s\' % (macoui)}, context_instance=RequestContext(request))
When I run this I get an error saying "nothing to repeat".
Thanks,
You have quite a few errors here.
You've correctly stated that there are two ways of getting parameters, then confused them both. If you're matching things in the urlconf, then you don't use request.GET to get them. Anyway, request.GET is only for querystring parameters - that is, URLs of the form www.domain.co.uk/?param=value where the ? is the necessary part.
If your URL is really www.domain.co.uk/macoui=001100 - without the ? - then you need to fix your regular expression as follows:
url(r'^macoui=(?P<macaoui>\d{6})$', 'domain.views.output'),
and your view as follows:
def output(request, macaoui):
However, if - as is much more likely - your URL is www.domain.co.uk/?macoui=001100 - with a question mark - then your URLconf should just be:
url(r'^$', 'domain.views.output'),
and your view becomes:
def output(request):
macaoui = request.GET.get('macoui', '')
I believe you have a problem in this line:
{'response': '\'%s\' % (macoui)}
As you're escaping the last apostrophe and the entire string is never closed. You'll be better off using the other string delimiters:
{'response': "'%s'" % (macoui)}
Good luck.
You should simply do.
url(r'^/.*', 'domain.views.output'),
then use URL, www.domain.co.uk/?macoui=001100
URL on your example what not proper as get parameters (request.GET) on request uri are followed after '?'

Categories

Resources