Reputation: 2665
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
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
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
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