Django HTTPResponseRedirect & Reverse with optional parameter - python

How do I use Django's Reverse with an optional parameter for info? I keep on getting
views.py:
def cartForm(request, prod):
if request.method=="POST":
quantity = request.POST.get('quantity', False)
if quantity:
add_to_cart(request, prod, quantity)
return HttpResponseRedirect(reverse("cart"))
#if no quantity indicated, display error message
return HttpResponseRedirect(reverse('products.views.info', kwargs={'prod': prod, 'error':True}))
def info(request, prod, error=False):
prod = Product.objects.get(id=prod)
return render(request, "products/info.html", dict(product = prod, error=error))
urls.py:
url(r'^(?P<prod>\d+)/', "products.views.info", name='info'),
I keep on getting the following error:
Reverse for 'products.views.info' with arguments '()' and keyword arguments '{'prod': u'2', 'error': True}' not found. 1 pattern(s) tried: ['products/(?P<prod>\\d+)/']

You can pass optional GET parameters as:
reverse('products.views.info', kwargs={'prod': prod})+'?error=true&some_other_var=abc'
reverse returns the resolved URL as string, so you can concatenate as many GET parameters as you want.

Not a direct answer but : why don't you just use the Messages framework (https://docs.djangoproject.com/en/1.6/ref/contrib/messages/).

Try with optional group in url:
# change (?P<error>\d+) to (?P<error>[a-zA-Z]+) to catch strings in error value
url(r'^(?P<prod>\d+)(?:/(?P<error>\d+))?/', "products.views.info", name='info'),
source: Making a Regex Django URL Token Optional

Adding an argument to the view function doesn't not make it into a URL pattern, in your case you have added the argument directy to the view method, but not mapped it to the URL.
Therefore, when you try to reverse the URL, a pattern that has error is not found, which is why you are getting the error.
You have two options:
Make the pattern optional which I do not recommend.
Map the same view to multiple URLs, with the optional one first as the patterns are matched in the order found:
url(r'^(?P<prod>\d+)/(?P<error>\d+)/', "products.views.info", name='info-error'),
url(r'^(?P<prod>\d+)/', "products.views.info", name='info'),
Now, in your view:
from django.shortcuts import redirect
def cartForm(request, prod):
if request.method=="POST":
quantity = request.POST.get('quantity', False)
if quantity:
add_to_cart(request, prod, quantity)
return HttpResponseRedirect(reverse("cart"))
#if no quantity indicated, display error message
return redirect('info-error', prod=foo, error=True)
Here I am using the redirect shortcut

Related

Issue on Django Url Routers

I an trying to make url router in Django which supports following URLs :
http://localhost:8000/location/configuration
http://localhost:8000/location/d3d710fcfc1391b0a8182239881b8bf7/configuration
url(r'^locations/configuration$',
location_config.as_view(), name="location-config"),
url(r'^locations/(?P<location_key>[\w]+)/configuration$',
location_config.as_view(), name="location-config-uri")
Whenever I tried to hit http://localhost:8000/location/configuration, it picked up the second URL routing format instead of picking up first one.
Error:
TypeError at /locations/configuration/ get() missing 1 required
positional argument: 'location_key'
Can anyone help me here what goes wrong with the url routing format?
Nope, it does pick the first pattern which has no arguments, however you're using the same view in both patterns and location_config view has required argument location_key which is not provided when first pattern matches the URL. That's what error message is saying.
So write another view which will not require location_key argument or alter this view definition: add default to the parameter
def location_config(request, location_key=None):
....
now it is not a "required positional argument".
django Will look for a pk when you are using a detail view by default. you have to override it by using get_object()
in your case
def get_object(self, queryset=None):
location_key = self.kwargs.get('location_key')
obj = Model.objects.get(id=location_key)
return obj

NoReverseMatch in Django 1.11

I know there are lot of questions already ask about this error but for some reason none of them work for me.
What i am trying to do?
I am trying to pass a variable from view ActivateAccount to another view result upon email confirmation.
What is the problem?
I am doing everything right according to docs and previously posted question about the same error but i still get this error:
Reverse for 'result' with keyword arguments '{'test': 'Email confirmed successfully!'}' not found. 1 pattern(s) tried: ['(?P<test>[\\w-]+)/$']
caller view.py:
def ActivateAccount(request, uidb64, token):
test = ''
if uidb64 is not None and token is not None:
...
test = "Email confirmed successfully!"
return HttpResponseRedirect(reverse('result', kwargs={'test': test}))
urls.py:
url(r'^(?P<test>[\w-]+)/$', views.result, name='result')
receiver view.py:
def result(request, test=None, *args, **kargs):
data = {'msg': test}
return JsonResponse(data) // this return the result to ajax 'GET'
And i would also like to know why is there double backslash \\ in the regex ([\\w-]) instead of single in the error. As in my url i have a single \ ([\w-]).
thanks for your time.
url(r'^(?P<test>[a-zA-Z!\s]+)/$', views.result, name='result')
use this urlpattern

Django How do i determine what arguments are missing?

Trying to access part of code by get request and receiving this error
NoReverseMatch: Reverse for 'homepage' with arguments '()' and keyword arguments '{}' not found. 0 pattern(s) tried: [] looked around for help and i think its that am missing some arguments.
here is request am using in my test
req = self.client.get('/password/reset/')
and the code it leads to is as:
class PasswordResetEmailView(FormView):
template_name = 'temp/password_reset.html'
form_class = PasswordResetForm
success_url = 'password_reset_ok'
def get(self, request, *args, **kwargs):
form = self.get_form(self.form_class)
return self.render_to_response(self.get_context_data(form=form))
any guidance ?
You ask specifically about "determining which arguments are missing", but should be irrelevant to your error.
Your error message states that it can't find any URL patterns matching the name "homepage", before attempting any argument matching. Therefore no URLs exist named "homepage" in your setup. If it was an argument mismatch, you'd see a list of named URLs in the error such as "tried X urls."
Either define a URL named home in your URLConf url(r'^home/$', 'home_view', name="homepage") or find the location that is calling reverse('homepage') and remove it. You will find this information in your traceback.

Django Redirect view with args

I have a problem with redirection in Django :
my view
def myP(request,namep):
return render(request,"site/myP.html")
def create(request):
nom="alaild"
....
return redirect(reverse(myP,namep=nom))
urls to this views
url(r'^create$', 'create', name='create'),
url(r'^myp/(?P<namep>\d+)','myP', name="myp"),
I have this error :
reverse() got an unexpected keyword argument 'name'
I want create view redirects to myP view but myP view have 1 argument and I don't know how make...
May be
reverse(myP, kwargs={'namep': nom})
In your view, nom is a string, but in your url pattern you are using \d+ (one or more digits).
A common approach is to accept a 'slug' which can contain letters, digits, underscores and hyphens:
url(r'^myp/(?P<namep>[\w-]+)','myP', name="myp"),
Then you need to fix the syntax of your reverse call. Either of the following should work.
reverse(myP, kwargs={'namep': nom})
reverse(myP, args=(nom,))

django named url not picking variables

I have the following url pattern -
url(r'^detail/(?P<var>[\w]+)/(?P<var_slug>[\w-])/$', 'player_detail', name='player_detail'),
In my view, I have the following -
model_dict = {"player":PlayerProfile, "event":PlayerEvent, "need":PlayerNeed}
def player_list(request, var=None, var_slug=None):
'''
displays the list of vars
'''
objs = model_dict.get(var).objects.filter(slug=var_slug).order_by('-creation_time')[:20]
template_name = "list_"+str(var)+"s.html"
return render(request, template_name, {"objs":objs})
In my templates I finally do the following -
details of Player
The error I get is following -
Reverse for 'player_detail' with arguments '()' and keyword arguments '{u'var': u'baseball', u'slug': u'obj.slug'}' not found.
What am I missing?
also, is it a good way to pick models dynamically depending on the variable in the parameter, and generating a template name on the fly?
slug='obj.slug' should be slug=obj.slug
Your regex doesn't match a .
Also you probably want[\w-]+ just like your other regex.. one or more [\w or -]

Categories