Karan Kumar
Karan Kumar

Reputation: 2665

How to retrieve max (pk) in python from a table database?

Okay it may sound stupid, I am very new to django and database.

What I'm trying to do it delete multiple entries from a database through a template.

Here is my view.py

def names(request):
    e = Clash.objects.all()
    for z in range(0 ,100): ##### need to change this 100 to max(pk)######
        if request.POST.get('check'+str(z), False):
            to_delete = Clash.objects.get(pk=z)
            print (to_delete)
            to_delete.delete()

    return render_to_response("names.html", locals() , context_instance = RequestContext(request))

Clash is my model, and here is the template I am deleting from:

<form method='POST' action=''>
       {% csrf_token %}
    {% for l in e %}
    <p>{{l.name }}

    {{l.second_name}}</p>

    <input type='checkbox' id="check{{l.id}}" name="check{{l.id}}"/>

    {% endfor %}

    <br>
    <input type='submit' value='Delete Selected'/>

</form>

How do I retrieve the max pk from the table? and place it in place of "100":
PS : I know the name and id are same of check-boxes (that don't matter)
PSS: This code works, I am able to delete multiple entries, but this is not good programming. How do I improve it ?

Upvotes: 1

Views: 220

Answers (3)

Daniel Roseman
Daniel Roseman

Reputation: 599876

Anentropic has pointed out the correct way to loop through things in Python: ie iterate over the list itself, not a range of numbers.

However this is still massively inefficient. What happens if you have a million rows in your database? You really don't want to iterate at all. Instead, you just need to ask the database directly to delete the rows you want.

In your template, change the checkbox so that it puts all the values in the same parameter:

<input type='checkbox' name="to_delete" value="{{l.id}}"/>

And now in your view, just get that list of values and delete it:

def names(request):
    to_delete = request.POST.getlist('to_delete')
    if to_delete:
        Clash.objects.filter(pk__in=to_delete).delete()

    return render_to_response("names.html", locals() , context_instance = RequestContext(request))

Upvotes: 3

ruddra
ruddra

Reputation: 51998

You can do like this:

last_item_pk = Clash.objects.last().pk

Check here for details: https://docs.djangoproject.com/en/dev/ref/models/querysets/#last

Upvotes: 0

Anentropic
Anentropic

Reputation: 33913

you don't do it like this:

e = Clash.objects.all()
for z in range(0 ,100): ##### need to change this 100 to max(pk)######

instead you can just iterate over the queryset directly:

for obj in Clash.objects.all():

this also means you also don't need to do this extra query on each iteration of the loop:

to_delete = Clash.objects.get(pk=z)

...because you already have that object loaded from the db, as obj.

So you can do:

def names(request):
    for obj in Clash.objects.all():
        if request.POST.get('check'+str(obj.id), False):
            print obj
            obj.delete()
    return render_to_response("names.html", locals() , context_instance=RequestContext(request))

Upvotes: 1

Related Questions