James L.
James L.

Reputation: 1153

Django 1.6: Pass dropdown value from one template another

I'm really new to Django and trying to get the value a user select from the dropdown menu on the index page, and use it in on the doclisting page. I'm trying to print the value on the doclistings page but it doesn't seem to print anything. I'm not sure if that's possible or not. any help would be much appreciated.

Here is index template where I've dropdown form

<div class="signup">
          <div class="form-group">
            <form action="/doclistings/" method="post" >{% csrf_token %}
            <select class="form-control" id="s1" name="selection">
              <option><b>Find a Doctor...</b></option>
              {% for value, text in form.selection.field.choices %}
                <option value="{{ value }}">{{ text }}</option>
              {% endfor %}
            </select>
<button class="btn btn-primary" type="submit"  name="submit" id="ss-submit">Find Doctors</button>

here is doclisting template where I'm trying to print the value from the selection

  <h2>{{selection}}</h2> 

here is the index method in views.py

def index(request):
    d = getVariables(request,dictionary={'page_name': "Home"})
    if request.method == "POST":
        form = DropdownSelectionForm(request.POST)

        if form.is_valid():
            selection = form.cleaned_data['selection']

            return HttpResponseRedirect('/doclistings', 'selection')
    else:
        form = DropdownSelectionForm()

    return render(request, 'meddy1/index.html', {'form': form})

here is the doclisting method in views.py

def doclistings(request):
    d = getVariables(request)
    doctors = Doctor.objects.all().order_by('-likes')
    paginator = Paginator(doctors, 20) #Show 20 doctors per page
    page =  page = request.GET.get('page')
    try:
        doctors = paginator.page(page)
    except PageNotAnInteger:
        doctors = paginator.page(1)
    except EmptyPage:
        doctors = paginator.page(paginator.num_pages)
    d['doctors'] = doctors
    d['paginator'] = paginator

    return render_to_response('meddy1/doclistings.html',d)

forms.py

MY_CHOICES = (
    ('Dermatologist', 'Dermatologist'),
    ('Dentist', 'Dentist'),
    ('Opthalmologist', 'Opthalmologist'),
)

class DropdownSelectionForm(forms.Form):
    selection = forms.ChoiceField(choices=MY_CHOICES, widget = forms.Select)

urls.py

url(r'^index/$', views.index, name='index'),
url(r'^doclistings/$', views.doclistings, name='doclistings'),

Upvotes: 0

Views: 2075

Answers (2)

mkriheli
mkriheli

Reputation: 1846

For a start, you're doing some of the things the hard/wrong way.

  • Don't render the fields yourself, Django forms can render the widgets, use {{form.as_p}} in the template.
  • Your form's method shouldn't be POST, which is used when changing things in the db. You should've used GET
  • Don't hard code urls in redirects, etc, decouple them. You're using named url patterns, so in your code reverse the names to get the url.
  • Use named groups to capture the param from the url you're redirecting to, e.g: url(r'^doclistings/(?P<group_name>\w+)/$', views.doclistings, name='doclistings'), your function will get the group_name arg as well (you should add it to the function signaure). Another option is to pass it as GET param /doclistings?group=xyz and in your function use request.GET to check if you have the group, and if so, filter further.

Some more nitpicks, advisory:

  • index and doclisting are functions, not methods.
  • You should use generic class based views like FormView and ListView which would have removed the boilerplate your using here.

HTH

Upvotes: 2

dhana
dhana

Reputation: 6525

If you haven't model, you can achieve this using django session,

Assuming you want database based sessions (Django also offers file based sessions, and cache based sessions):

Open settings.py and find MIDDLEWARE_CLASSES. Add 'django.contrib.sessions.middleware.SessionMiddleware' to the list.
Find INSTALLED_APPS in the same file and add 'django.contrib.sessions' there.
Run manage.py syncdb from the command line.

After the initial setup you can use request.session in your views to store information between requests.

def index(request):
    d = getVariables(request,dictionary={'page_name': "Home"})
    if request.method == "POST":
        form = DropdownSelectionForm(request.POST)

        if form.is_valid():
            selection = form.cleaned_data['selection']
            request.session["selection"] = request.POST['selection']

            return HttpResponseRedirect('/doclistings')
    else:
        form = DropdownSelectionForm()

    return render(request, 'meddy1/index.html', {'form': form})

In doclist view,

def doclistings(request):
    d = getVariables(request)
    doctors = Doctor.objects.all().order_by('-likes')
    paginator = Paginator(doctors, 20) #Show 20 doctors per page
    page =  page = request.GET.get('page')
    print request.session["selection"]
    try:
        doctors = paginator.page(page)
    except PageNotAnInteger:
        doctors = paginator.page(1)
    except EmptyPage:
        doctors = paginator.page(paginator.num_pages)
    d['doctors'] = doctors
    d['paginator'] = paginator

    return render_to_response('meddy1/doclistings.html',d)

For other things you can do with the request.session object see the documentation.

Upvotes: 2

Related Questions