1

I want to pass a list through the url. But when i tried, i got some errors. So how can i do that. Somebody please help me..

this is my view

def add_student(request):

    if request.method == 'POST':
        student_list = []
        student_name = request.POST.getlist('student_name')
        student_phone = request.POST.getlist('student_phone')

        zipped = zip(student_name,student_phone)

        for student_name,student_phone in zipped:

            student_object = Student(
                                student_name=student_name,
                                student_phone=student_phone
                            )
            student_object.save()

            student_list.append(student_object.id)

        return HttpResponseRedirect(reverse('students:view_students', args=student_list))
**# in the above code it throwing some errors** 
    else:
        return render(request,'students/add_student.html')


def view_students(request,student_list=None):
    if student_list:
        instances = Student.objects.filter(id__in=student_list)
    else:
        instances = Student.objects.filter()
    context = {}
    context['instances'] = instances

    return render(request,'students/view_all_student.html',context)

this is my url :

url(r'^view-students/(?P<student_list>\w+)/$',views.view_students, name='view_students'),

this is the error i got.

NoReverseMatch at /app/product/add-product/

Reverse for 'view_products' with arguments '(14, 15)' and keyword arguments '{}' not found. 1 pattern(s) tried: [u'app/product/view-products/(?P<pd_list>.*)/$']

here (14,15) are the list items.

If the question is not correct. Somebody please correct the question.

DavidS
  • 276
  • 1
  • 17
Thameem
  • 3,426
  • 4
  • 26
  • 32
  • 2
    As a general warning, you should be careful about fetching data from `request.GET` or `request.POST` and sticking it straight into a filter without validating it. You are allowing the user to view any items from the table that they want, just by tweaking the url or post data. – Alasdair Feb 18 '16 at 16:16
  • @Alasdair ....thanks...using 'uuid' instead of id. is that a good option??...what is the alternate solution for that??...if you can please let me know – Thameem Feb 18 '16 at 17:02
  • 1
    That's too broad a question to answer fully in the comments. UUIDs have the advantage that they are not guessable. Other times, you might have a foreign key, for example from Student to Teacher. Then you would only let the logged in user view students that they currently teach. Other good changes would be to require login for your view, and perhaps restrict access to users with a 'view students' permission. – Alasdair Feb 18 '16 at 17:13

1 Answers1

3

If all you want to do is render a list you should just do that.

def add_student(request):
    if request.method == 'POST':
        student_list = []
        student_name = request.POST.getlist('student_name')
        student_phone = request.POST.getlist('student_phone')

        zipped = zip(student_name,student_phone)

        for student_name,student_phone in zipped:
            student = Student.objects.create(student_name=student_name,
                                             student_phone=student_phone)
            student_list.append(student)

        return render(request,'students/view_all_student.html', {'instances': student_list})
    else:
        return render(request,'students/add_student.html')

However, Your issue seems to be concerned with users double posting this request. To remedy this you could pass them as a get parameter

def add_student(request):
    if request.method == 'POST':
        student_list = []
        student_name = request.POST.getlist('student_name')
        student_phone = request.POST.getlist('student_phone')

        zipped = zip(student_name,student_phone)

        for student_name,student_phone in zipped:
            student = Student.objects.create(student_name=student_name,
                                             student_phone=student_phone)
            student_list.append(str(student.id))

        redirect = HttpResponseRedirect(reverse('students:view_students'))
        redirect['Location'] += '&'.join(['students={}'.format(x) for x in student_list]))
        return redirect
    else:
        return render(request,'students/add_student.html')

def view_students(request):
    students = request.GET.getlist('students')
    if students:
        students = [int(x) for x in students]
        instances = Student.objects.filter(id__in=students)
Sayse
  • 42,633
  • 14
  • 77
  • 146
  • thanks for your answer.. i have experienced some problem when i try to do as you mentioned , whenever i refresh the page ,all the data is stored in the database again.. – Thameem Feb 18 '16 at 14:16
  • @actually i want this results to go to some other view...But according to your answer the results remains in the same view and whenever we refresh the page ,data will be stored in the database again...so inorder to overcome this problem , i am passing the list to the seperate view to show the success page..if my language is not in a polite way ,please forgive me , my english is not so good – Thameem Feb 18 '16 at 14:21
  • 4
    Yes it is good practice to redirect after a POST request, to avoid the user double-posting the data if they refresh the page. – Anentropic Feb 18 '16 at 14:24
  • @Thameem - I've updated my answer, you shouldn't need the student list parameter now (in your students view) – Sayse Feb 18 '16 at 14:50
  • @Sayse thanks a lot for spending your time to help me...let me try your answer... – Thameem Feb 18 '16 at 15:06
  • @Sayse I haven't tried it but I think to get a list from a querystring var you need to repeat the key, like `?students=13&students=14` ...this is the main reason that Django `QueryDict` class exists... to convert these repeated keys into a single key containing a list of values – Anentropic Feb 18 '16 at 15:56
  • @Anentropic - I did try it with Firefox not sure about other browsers... [A different answer that used this notation](http://stackoverflow.com/a/17021910/1324033) :) – Sayse Feb 18 '16 at 15:58
  • @Sayse i am getting a students list like this " [u'23,24,25,26'] " and when i try to convert this to integer like this "sd_list = [int(x) for x in students]" in view_students ...it throws some errors ...now i am googling how can i convert unicode list to integer list – Thameem Feb 18 '16 at 15:58
  • 2
    If you have `?students=23,24,25,26` in the URL, then you want `students = request.GET.get('students')` instead of `getlist`. Then convert to a list of integers with `sd_list = [int(x) for x in students.split(',')`. – Alasdair Feb 18 '16 at 16:06
  • 1
    @Thameem - (and all), I've changed the way that the get params are constructed to use the other notation which should fix your issues. Apologies for not testing further! (Thanks Anentropic and Alasdair) – Sayse Feb 18 '16 at 16:09
  • 1
    In my comment above, it should be `students = request.GET.get('students', '')`, otherwise `students.split(',')` will throw an error when the key isn't in `request.GET`. – Alasdair Mar 08 '16 at 13:38