Get full request URL from inside APIView in Django REST Framework - python

Is there a method, or an attribute in request object that I can access to return me the URL exactly as the client requested? With the query params included?
I've checked request.build_absolute_uri after looking at this question but it just returns the URL without the query params.
I need the URL because my API response returns the URL for the "next page" of results. I could build it from the query_params attributes, but this view takes a lot of query params and some exclude others, so having access to the request url would save me a lot of pain.

To get full path, including query string, you want request.get_full_path()

Related

In Django, can I use context in redirect?

I am trying to use redirect with context but I get a NoReverseMatch exception. Code is as follows:
return redirect(reverse('td:success', kwargs={ 'data': my_data }))
When I use render, all goes well and I am able to access the context in the template. But I want redirect instead.
enter image description here
But I want redirect instead.
You can't. The redirect(…) function [Django-doc] simply returns a HTTP response that contains the URL to visit next. The browser will then visit that URL, it is thus the browser that makes the next HTTP request, and the previous request and response are "destroyed". You thus need the database, cookies, session variables, URL parameters, etc. to pass data between the two requests.
If you use a URL parameter, you can thus add data to this. In that case, your code snippet can be simplified to:
return redirect('td:success', data=my_data)
there is no need to work with reverse(…) since redirect(…) will call reverse(…) internally.

How to get query params in fast api from POST request

Client might send multiple query params like:
# method = POST
http://api.com?x=foo&y=bar
I need to get all the query params and extract it as a string x=foo&y=bar from the POST request.
Is there a way to do this on fast api? I could not find it on their docs.
NOTE :
We are not sure of the names of the params before hand.
Depending how you want to use the data, you can either use request.query_params to retrieve a immutable dict with the parameters, or you can use request.url to get an object representing the actual URL. This object has a query property that you can use to get the raw string:
from fastapi import FastAPI, Request
import uvicorn
app = FastAPI()
#app.get('/')
def main(request: Request):
return request.url.query
uvicorn.run(app)
This returns the given query string /?foo=123 as foo=123 from the API. There is no difference between a POST or GET request for this functionality.

Calling View in API Request Factory when testing in Django Rest Framework

Whenever we test an API in Django Rest Framework using API Request Factory why do we call the view when we are already passing the url .
Look at the following code for better understanding .
request = self.factory.post("/api/v1/menu/", data)
views = MenuResource.as_view({"post": "post"})
response = views(request)
response.render()
self.assertEqual(201, response.status_code)
In the above code we are calling the url as well as calling the view . View is being called for rendering the view on the url but that is not what my use case is . I just want to test the response code . Is there a way of getting the response code without rendering the view as that is an over kill for my use case .
I have looked for other methods except for using API Request Factory but i just wanted to know why does API Request Factory need to call the view . Is there any advantage in comparison to other API Testing modules present in Django Rest Framework.
That is because you are not making a request to the URL.
request = self.factory.post("/api/v1/menu/", data) simply creates a request object for you to use it does not actually make the request.
So testing the view in your case consists of creating a request object and passing it to the view which mimics the way an actual request would be passed and processed by that view.
If you want to send actual request you need to mock a test server which will handle the actual requests.

Django template tag to insert or replace URL parameter

Is anyone aware of a Django template tag that takes the current path and query string and inserts or replaces a query string value?
e.g. given a request to /some/custom/path?q=how+now+brown+cow&page=3&filter=person
The call {% urlparam 'page' 4 %} would generate /some/custom/path?q=how+now+brown+cow&page=4&filter=person.
This wouldn't be too difficult to write from scratch, but as this seems like a very common task, I would expect a tag like this to be built-in. However, after reading through the docs and googling, I can't seem to find anyone's who's publicized such a tag.
Since I haven't used these tools by my own, I'll just refer you:
django-url-tools has url_params template tag that seems to do what you want
django-more-template-tags-and-filters has some helper tags for manipulating urls and parameters
FYI, I've personally used jsurl library for this kind of url manipulations in javascript.
Hope that helps.
Here's how I did it on a Django 1.3 project. Like you I expected to find this built in, but ended up coding it in the view:
def remove_url_param(url, params):
if not isinstance(params, list):
params = [params,]
if isinstance(url, unicode):
# urlencode doesn't like unicode
url = url.encode('utf8')
(scheme, netloc, path, query, fragment) = urlparse.urlsplit(url)
param_dict = parse_qs(query)
for p in params:
try:
del(param_dict[p])
except KeyError:
pass
query = urllib.urlencode(param_dict, True)
return urlparse.urlunsplit((scheme, netloc, path, query, fragment))
Then I used this to create base URLs:
page_url_unordered = putils.remove_url_param( request.get_full_path(), ['order', 'ajax'] )
Then in the template:
Price
Size
I want to render a series of pagination links on a search page. The
URL contains several query parameters (like in my example). The
pagination code that renders the pagination links shouldn't have to be
explicitly given all these parameters. Django's admin seems to have
this behavior everywhere.
This is enabled by adding django.core.context_processors.request to TEMPLATE_CONTEXT_PROCESSORS (its not enabled by default). This will add a request variable to your templates, which is the HttpRequest object.
From there, you can use {{ request.get_full_path }} to get the current URL with the complete query string, and then append your custom query to it.
If your page is /search?q=foo+bar, and you want a new link to be /search?q=foo+bar&page=4, page 4.

How to alter the URI in django?

http://packages.python.org/django_simple_feedback/ref/request-response.html tells that the absolute URI is built using the server variables available in this request. So, How can I alter the URI using HttpRequest.build_absolute_uri.
My situation is:
/foo/bar/2/ is the url having corresponding view load_view(request) Before rendering the template I want to alter the URI by attaching the new absolute URI in the request. So, that My templte renders on the URL /foo/.
You can use django.shortcuts.redirect to redirect to a different location:
def load_view(request):
return redirect('/foo/')
You will still need a corresponding view setup for that url, of course, as this will cause the user's browser to redirect to /foo/. If you want to change the url without refreshing the page, you can do this with HTML5 now:
window.history.pushState('','foo','/foo/');

Categories