mmrti
mmrti

Reputation: 71

Django view not accepting url parameters

I've been trying to develop a simple web app in django, but I have come across an error. Basically the parameters passed in the url are not accepted and I get

TypeError at /NECapp/offers/ offers() takes exactly 2 arguments (1 given)

http://dpaste.com/757822/ for the full trace

A quick rundown of the app: the user puts in a postal code and is given a list of objects that are related to that value. No matter what I tinker with, the code always breaks at this point with different errors, so I'll be dumping most of the code here. Due to the mount of things I have tried, there are probably unnecessary lines of code in the imports and maybe elsewhere, so beware.

views.py

from django.shortcuts import render_to_response
from django.http import HttpResponse
from models import Offer, ZipCode
from django.http import HttpRequest

def index(request):
    return render_to_response('NECapp/index.html')

def enterzipcode(request):
    return render_to_response('NECapp/enterzipcode.html')

def offers(request, zip):
    return HttpResponse('you entered %zip' %(zip))

urls.py of the app

from django.conf.urls import patterns, include, url
from django.views.generic import ListView

from NECapp.models import Offer
from NECapp import views


# Uncomment the next two lines to enable the admin:
from django.contrib import admin
admin.autodiscover()

urlpatterns = patterns('NECapp',
    url(r'^$', 'views.index', name='index'),
    url(r'^enterzip/$', 'views.enterzipcode', name='zipcode'),
    url(r'^offers/(?P<zip>\d{5})/$', 'views.offers', name='offers'),
    url(r'^offers/$', 'views.offers'),   
)

I would greatly appreciate any kind of help!

Upvotes: 0

Views: 3076

Answers (3)

Vivek S
Vivek S

Reputation: 5540

The error comes because when you call the URL /NECapp/offers/?zip=55104,since you have passed zip as query string and not as parameter, the second offers URL pattern gets called and since you have'nt given any default arguments it shows the error. Exception Value: offers() takes exactly 2 arguments (1 given)

def offers(request, zip):
    return HttpResponse('you entered %zip' %(zip))

You need to fix two things:

1)As per your URL pattern,your request URL should be /NECapp/offers/55104/ 2)Whenever second URL pattern gets called you will get error.Fix it by default args.

def offers(request, zip=""):
    return HttpResponse('you entered %zip' %(zip))

if you are trying to post the data via form,put method="POST" in your form tag and you dont need two URI patterns as all form data will be available in your request.POST dictionary. HTML:

<form action="/NECapp/offers/" method="post">

URLS.py:

url(r'^offers/$', 'views.offers'),   

Views.py:\

def offers(request):
    zip=request.POST.get("zip")
    return HttpResponse('you entered %zip' %(zip))

Upvotes: 1

Tadeck
Tadeck

Reputation: 137300

To make it work (NECapp/offers/ URL), you will need to just add default value to zip.

This is because you execute views.offers view in two cases, depending on the requested URI:

  1. When there is something after "/offers/" (you have zip code passed) - for this you have your url pattern second from the end (the one with name='offers'),
  2. When there is nothing after "/offers/" (for this you have your last URL pattern).

Your view would look similarly to this:

def offers(request, zip=None):
    if zip is None:
        # No zip has been set (/offers/)
        return HttpResponse('you did not enter anything')
    else:
        # Some zip has been set (/offers/some_zip)
        return HttpResponse('you entered %zip' %(zip))

EDIT:

Vivek correctly noted, that you are invoking http://localhost:8000/NECapp/offers/?zip=55104 instead of http://localhost:8000/NECapp/offers/55104. This is why you get your last URI pattern matched (the one with r'^offers/$' rule) and the view is invoked without parameters. If you will use my solution, you will get "you did not enter anything" in response, because you are not passing zip within URL (actually you are, but in query string, and you should pass it in the main part of the URL instead, if you want to use your URLconf).

So, in short, use my solution and pass zip in URL like that: http://localhost:8000/NECapp/offers/55104. Alternatively you can just get rid of this pattern with zip and just use request.GET.get(zip) to get zip from query string.

Upvotes: 0

rh0dium
rh0dium

Reputation: 7032

Look closely at your urls.py

url(r'^offers/(?P<zip>\d{5})/$', 'views.offers', name='offers'),

conflicts with

url(r'^offers/$', 'views.offers'),   

HTH!

Upvotes: 0

Related Questions