django url dispatcher with HTTP GET arguments - regex

In a urls.py file:
url(r'^api/user_info/(?P<username>[a-zA-Z\d]+)\&', 'corresponding.view')
url(r'^api/user_info/(?P<username>[a-zA-Z\d]+)', 'corresponding.view')
There will always be HTTP Get arguments to /api/user_info/username.
The problem is that in the corresponding.view function, username will evaluate to something like "myusername?clientversion=2.0", instead of it evaluating to "myusername" and request.GET['clientversion'] = "2.0".
The first url call is to try to catch the ampersand in there, but it doesn't help.
Thanks in advance.

See this question; you don't access query parameters using Django's URLConf. Trying to process ? or & characters using the URL resolver will not lead to happiness.
Just use the following URL pattern:
url(r'^api/user_info/(?P<username>\w\+)/$', 'corresponding.view')
and access the clientversion query parameter in your corresponding.view() function:
def view(request):
client_version = request.GET.get('clientversion')
...
Or, if you're saying it should be mandatory,
from django.http import Http404
def view(request):
try:
client_version = request.GET['clientversion']
except KeyError:
raise Http404

Related

How can I send data from the get_avatar() (Google Sign In) to my template?

I have integrated Google Sign In using social_django app although in order to get the profile photo / avatar of the user I have used get_avatar through django pipeline. Now the problem is that how can I send the url received in the get_avatar function to one of my templates?
I have tried using Render, HTTPResponse, HTTPResponseRedirect, JSONResponse but I'm not getting the desired results.
get_avatar():
def get_avatar(backend, strategy, details, response,
user=None, *args, **kwargs):
if backend.name == 'google-oauth2':
try:
url = response["picture"]
except KeyError:
url = response['image'].get('url')
The rendering of get_avatar function returns a empty dictionary to the template. Rather it should return the URL which we get from get_avatar function.
Thanks in advance :)

How to redirect with querystring in django urlpatterns?

I'm looking for a way to make a redirect from one url to another with query string parameter.
Is it possible to get a redirect from /orders/ to /orders-new/?queryParam=1
How should I change RedirectView in a first line?
url(r'^orders/$', RedirectView.as_view(pattern_name='orders-new'),
name='orders'),
url(r'^orders-new/$', orders_list_new, name='orders-new'),
Try to use url argument like this:
from django.urls import reverse_lazy
url(r'^orders/$', RedirectView.as_view(url='{}?queryParam=1'.format(reverse_lazy('orders-new'))),
name='orders'),
You can do one thing, For a quick solution Write a simple view for /orders/ url and in it's dispatch method redirect url to /orders-new/ with any string parameters
You can redirect as below
def dispatch(self, request, *args, **kwargs):
return redirect(reverse('<app_name>:orders')

django HttpResponseRedirect and ABSOLUTE_URL_OVERRIDES

I'm new to django (1.5.1) and got a bit stuk with HttpResponseRedirect.
If I understand right that needs a static string, and when you want it to dynamic redirect, you get a reverse() or a get_absolute_url()
I think I get the part of the get_absolute_url, but I'm stuck on redirecting to the following url (first is mysite.urls.py second is my characters.view.py
url(r'^users/', include('characters.urls')),
url(r'^(?P<user_id>\d+)/characters/$', views.user_characters, name='user_characters'),
from this view:
if new_char_form.is_valid():
#save form with commit=False
new_char_obj = new_char_form.save(commit=False)
#set user and save
new_char_obj.user = user
new_char_obj.save()
return HttpResponseRedirect('%s/characters/' % user.id)
So I know I can't use the HttpResponseRedirect that way, and since I can't include a get_absolute_url function in the user model, I found the next option.
Include this in my settings
ABSOLUTE_URL_OVERRIDES = {
'auth.users': lambda o: "/users/%s/" % o.id,
}
but then I have no clue how to call for that.
Can someone please give me help (sort of stuck on this for some time)
With kind regards
Hans
The easiest way to redirect to the user_characters view is to use the redirect shortcut.
from django.shortcuts import redirect
# in the view
return redirect('user_characters', user.id)
This is equivalent to using HttpResponseRedirect and reverse
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
# in the view
return HttpResponseRedirect(reverse('user_characters', args=[user.id]))
If you want to use ABSOLUTE_URL_OVERRIDES to override the get_absolute_url method for the User model, you have to make sure that the url matches the format of your view named user_characters.
ABSOLUTE_URL_OVERRIDES = {
'auth.users': lambda o: "/users/%s/characters/" % o.id,
}
You would then be able to call user.get_absolute_url() in your views, and do
return HttpResponseRedirect(user.get_absolute_url())
Or, since the redirect shortcut allows you to pass a model instance:
return redirect(user)

Django and testing local URLs exist

I have a model which needs to store URLs which will be part of the Django environment. If I was storing normal URLs, I'd use models.URLField, and use verify_exists to make sure the URL actually exists.
However, this doesn't work that great in development, since the dev server is single-threaded, it hangs indefinitely, since it can't process two requests at once.
I was hoping to do something using resolve(), but am having difficulty adapting the function myview at the end of that documentation page to a version which does not take a request, since I want to check that a given local URL can be resolved, and called without a 404 being raised, from a blank session.
I was hoping to do this with a validator, something like this:
def validate_local_url(value):
try:
view, args, kwargs = resolve(value)
view(*args, **kwargs)
except Resolver404:
raise ValidationError(u'%s is not a local URL (not a valid URL)' % value)
except Http404:
raise ValidationError(u'%s is not a local URL (does not exist)' % value)
However, this fails without a valid request object being passed into kwargs. How do I generate a dummy (blank) request object? I've tried just using django.http.HttpRequest.
Just a wild idea, not sure if it will be helpful. Have you considered naming the urls and using reverse()? Reverse will work if the URL is valid and will fail when it is not.
Are you cool with using the django test Client?
If so, this should do it:
from django.test.client import Client
def validate_local_url(path):
c = Client()
try:
resp = c.get(path)
if resp.status_code == 404:
raise ValidationError(u'%s is not a local URL (does not exist)' % value)
except:
raise ValidationError(u'%s is not a local URL (not a valid URL)' % value)
Just, you know, make sure under penalty of death that validate_local_url can never be called by a local GET request, otherwise someone can trivially set your server on an infinite loop:
# urls.py
url('^infinite_loop/$', 'myapp.infinite_loop', 'infinite_loop')
#views.py
def infinite_loop_view(request, template_name="blah.html", form_class=MyForm):
my_form = form_class(request.REQUEST or None) # yes, admittedly this is dumb
if my_form.is_valid():
return HttpResponse("Congratulations! Your path was totally valid.")
return render_to_response(template_name, locals(), RequestContext(request))
And then:
http://example.com/infinite_loop/?path_field=infinite_loop

redirect to another page instead of recieving Django standarf 404 error

i have something like this in my views.py
instance = get_object_or_404(register,pk=request.user.id)
Now if there is no related object against this user i receive i standard django 404 eror
saying no matches found.
what i want here is instead of receiving this 404 error redirect it to another page say "something.html". but i dont know how. i am using method = "POST"
is there any way to redirect it to other page instead of receiving a 404 error
using a try/except block you can redirect if the object is not found
try:
instance = register.get(pk=request.user.id)
except register.DoesNotExist:
return HttpResponseRedirect('url that renders something.html')
FYI, definition of django get_object_or_404 function looks like this
def get_object_or_404(klass, *args, **kwargs):
"""
Uses get() to return an object, or raises a Http404 exception if the object
does not exist.
klass may be a Model, Manager, or QuerySet object. All other passed
arguments and keyword arguments are used in the get() query.
Note: Like with get(), an MultipleObjectsReturned will be raised if more than one
object is found.
"""
queryset = _get_queryset(klass)
try:
return queryset.get(*args, **kwargs)
except queryset.model.DoesNotExist:
raise Http404('No %s matches the given query.' % queryset.model._meta.object_name)
from the docs, If you raise Http404 at any point in a view function, Django will catch it and return the standard error page for your application, along with an HTTP error code 404.
look at customizing error views if you want to render a custom 404.html based on the context variables
Depending on what the Big Picture is, you might want to look at django.contrib.flatpages and see what they are doing. Basically they are dealing with the 404 in middleware and then looking at the path to decided if there is something they can return. I have used variations on this on a couple of sites.