Python Django: urls.py questions - python

Need a little help with my urls.py and other stuff.
How can I replicate this in Django?
1) When user requests a non-existent page it will redirect to one up the directory level. Ex: example.com/somegoodpage/somebadpage should be redirected to example.com/somegoodpage.
2) When user requests page example.com/foo/bar/?name=John it will make url to example.com/foo/bar/name=John
3) When user requests page example.com/foo/bar/John it will change url to example.com/foo/bar/name=John.
Any help is greatly appreciated. Thank You.

For 1), if you don't want to do a separate route for every single route on your website, you'll need middleware that implements process_exception and outputs an HttpResponseRedirect.
For 2 and 3, those are rules that are presumably limited to specific routes, so you can do them without middleware.
2 might be doable in urls.py with a RedirectView, but since the relevant bit is a query string argument, I would probably make that an actual view function that looks at the query string. Putting a ? character in a url regex seems strange because it will interfere with any other use of query strings on that endpoint, among other reasons.
For 3, that's a straightforward RedirectView and you can do it entirely in urls.py.

according to django doc for number 1:
django URL dispatcher runs through each URL pattern, in order, and stops at the first one that matches the requested URL, so add a pattern that matches "somebadpage"s and assign it to a view which redirects the user to "somegoodpage".
for number 2:
the doc says "The URLconf searches against the requested URL, as a normal Python string. This does not include GET or POST parameters, or the domain name."
so i don't think that you can get the "?name=John" in url dispather, so if you describe what you want to do maybe I can help better
and for 3:
to capture bits of the URL and pass them as positional arguments to a view you should use named regular-expression groups, for example :
url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', 'news.views.month_archive'),
and the request to /articles/2005/03/ would call the function news.views.month_archive(request, year='2005', month='03'), instead of news.views.month_archive(request, '2005', '03').
hope this helped :)

Related

URL pattern for query string parameters Django REST Framework

This is my current url path is as http://localhost:8000/api/projects/abcml/2021
and in the urls.py page I am passing as path("api/projects/<str:project_handle>/<int:year>", functionname...) and in the view, I accept this parameters with self.kwargs.get method.
I want to pass url as this format http://localhost:8000/api/projects/abcml/?year=2021
What changes do I need to make in url pattern?
I tried this path("api/projects/<str:project_handle>/?year=<int:year> but did not seem correct also in the view page, instead of self.kwargs.get I changed it to self.request.query_params.get for year parameter. That did not work either. Error it throwing is Page not found (404).
The query string [wiki] is not part of the path, and therefore can not be matched.
You thus specify as path:
path('api/projects/<str:project_handle>/', functionname)
In the view, you can access the data with self.request.GET['year'] and this will return a string or a KeyError in cas the year was not provided in the query string.

Why do I need to specify HTML file in render()

Why do I need to give html file name in render() - I have already set url in my project file in urls.py in django
urls.py
url('view-books',views.viewBooks)
views.py
def viewBooks(request):
books=models.Book.objects.all()
res=render(request,'BRMapp/view_book.html',{'books':books})
Why can I not give in render view-books?
i think you have typo
def viewBooks(request):
books=models.Book.objects.all()
context = {"books":book}
return render(request,'BRMapp/view_book.html',context)
your question why you need html file name in render because render is a function it takes 3 arguments 1st is request second is "path of the html file" 3rd is the context
further explaination
Do you have basic idea how django work first of first you are not giving url in render you are giving path to render which template should be render . django follow mvc pattern you read on it but to simplify it urls just have the routing task they are just there to filter routes not to do any thing in url you can give 3 arguments two are compulsary first the path by which it recognize that the time has come to act the second the function name which direct him where to go then its function responsibilty to process the data
Unfortunately, you didn't return anything in your view. So you need to add return to your function:
def viewBooks(request):
books=models.Book.objects.all()
return render(request,'BRMapp/view_book.html', {'books':books})
You might want to take a look at this tutorial.
https://yourwebsite/view-book is not the same as BRMapp/view_book.html, Django needs to know that one corresponds to the other.
The routing in Django works like this:
The user sends a request to Django with a url.
Django looks through your urls in urls.py for a path that matches what was requested.
When it finds a path, like view-books, that path has a view. The view is just a function (viewBooks()), and Django executes it.
The view function is expected to return the content that the user will see. You could, if you wanted, write the whole page by hand as a string in the return line of viewBooks(), but that's inconvenient, so instead you tell Django to make the page for you, starting from a template. To do so, you call render().
What render() does is take the template and replace all parts that need to be replaced for the user that will see it. But to know what the initial content will look like, it needs to read it from somewhere, and that's the HTML file BRMapp/view_book.html.
The HTML file doesn't need to have the same name as the view, you could have called it foobar.html and it would have worked the same. But regardless of its name, you need to tell Django that you want to use a file (render() tells Django that), and you need to tell Django where that file is. You'll have many different files in different places with different names, and it can happen that you have the same name for templates in different directories, so Django will not attempt to guess which one you want: you'll have to put its path inside render() so that Django knows where to start building the page.
If you gave the URL to render() instead of the path to the file, Django would get to point 5 and then back again to 1 to figure out what that URL means, and so on and so forth forever.

Django url dispatcher using repath arguments

In my django app . I have endpoints for a package with the months like :
www.example.com/cart/packagename/months
www.example.com/cart/stater/3
which i dont think will good as an url pattern I want something like :
www.example.com/cart/?package=stater&months=3
And also want to encode the parameters 'package=stater&months=3'
If anyone has any suggestions how to achieve that with django let me know. because before i worked with laravel and its pretty simple to do.
Its also very simple to do in Django. The part after question mark here is called URL Query String. You can get its value by:
def cart_view(request):
packages = request.GET.get('package')
months = request.GET.get('months')
As URL query string has nothing to do with actual URL, so you need to change your url.py to:
path('cart/', cart_view,name='cart_view'),

django query parameter with space

I have a URL that takes query parameters that might have spaces in them. I know it looks pretty simple, but my regex is not working for me.
Here's my URL pattern definition:
url(
r'^item_info_details_view/(?P<itemno>[\w \/&-]+)/$',
'purchasing.views.item_info_details_view'),
The itemno could be a phrase such as FAX MODEM which contains a space.
However, when I pass such a parameter to it, the URL in my browser is
http://localhost/item_info_details_view/FAX%20MODEM/
And displays this debugging info:
Using the URLconf defined in urls, Django tried these URL patterns, in this order:
^$
The current URL, item_info/FAX MODEM/, didn't match any of these.
The problem doesn't seem to be the space, but the fact that you've got "item_info_details_view" in the urlconf but "item_info" in the actual URL.
(As written by #daniel-roseman)

Django restapi passing parameter to read()

In the test example http://django-rest-interface.googlecode.com/svn/trunk/django_restapi_tests/examples/custom_urls.py on line 19 to they parse the request.path to get the poll_id. This looks very fragile to me. If the url changes then this line breaks. I have attempted to pass in the poll_id but this did not work.
So my question is how do I use the poll_id (or any other value) gathered from the url?
Views are only called when the associated url is matched. By crafting the url regex properly, you can guarantee that any request passed to your view will have the poll_id at the correct position in the request path. This is what the example does:
url(r'^json/polls/(?P<poll_id>\d+)/choices/$', json_choice_resource, {'is_entry':False}),
The json_choice_resource view is an instance of django_restapi.model_resource.Collection and thus the read() method of Collection will only ever act on requests with paths of the expected format.

Categories