Reputation: 4043
I have seen several posts that describe deleting items in Django with views and check boxes. I have accomplished deleting single items with AJAX. My current problem is that I cannot figure out how to delete multiple items with check boxes and AJAX in my Django application.
I originally used Django's GCBV, DeleteView
, and this worked for single-object deletions. But as @Craig Blaszczyk points out, the DeleteView
is for just that: deleting a single object. So I need to write a new view to delete multiple objects with an accompanying form and AJAX call that sends the ids
array.
I have this working but it feels clunky and doesn't work very well. My AJAX script is here:
$.ajax({
type: 'POST',
url: '/dashboard/images/delete/',
data: {'ids': ids},
success: function() {
console.log(date_time + ": AJAX call succeeded.");
},
error: function() {
console.log(date_time + ": AJAX call failed!");
console.log(date_time + ": Image ID: " + ids + ".");
}
});
In this script (above the section shown here) I build an array of ids and send as data.
So in my CBV, I'm collecting the selected ids and deleting them:
def post(self, request, *args, **kwargs):
form = self.form_class(request.POST)
GalleryImage.objects.filter(pk__in=request.POST.getlist('ids[]')).delete()
return render(request, self.template_name, {'form': form})
Here is the form I'm using:
class DeleteImagesForm(forms.Form):
ids = forms.ModelMultipleChoiceField(
queryset=GalleryImage.objects.all(),
widget=forms.CheckboxSelectMultiple(),
)
What is a better way to be doing this? I feel like I hacked my way to this solution without very good practices in place.
Also, even thugh it seems to be working, I feel like I should be deleting these images after calling if form.is_valid()
.
Any final words before the bounty ends?
Upvotes: 4
Views: 1926
Reputation: 4306
You can select checkbox and store the values of id's in one array and set that array to value of input tag.
Ex.
function updateTextAreanew() {
var allVals = [];
$('.questions_checkbox :checked').each(function() {
allVals.push($(this).next().val());
});
$('.ups1').val(allVals);
}
$(function() {
$('.questions_checkbox input').click(updateTextAreanew);
updateTextAreanew();
});
Here we are detecting the checkbox click and stoaring the values in allVals array.
Now send this array which has all the id's to view using ajax and run for loop in view and delete the object.
in views
@csrf_exempt
def deleteitems(request):
newdata = request.user
profiledata = UserProfile.objects.get(user=newdata)
swid = request.POST.getlist('newval[]') # ajax post data (which have all id's of GalleryImage objects)
for one in swid:
obj = GalleryImage.objects.get(id=one).delete()
response = json.dumps({'data':'deleted'})
return HttpResponse(response, mimetype="application/json")
Upvotes: 1
Reputation: 972
Your view is a DeleteView
, which by definition only works with one item. To be able to delete multiple items I'd suggest that you make a new View
, which has a form which expects the ids to which you want to delete. You'll then be able to write a ProcessFormView
which iterates over the ids in the form and deletes each one.
Here's a sample view:
class MyView(FormView):
form_class = MyForm
template_name = 'mytemplate.html'
def form_valid(self, form):
# Process your ids here
print form.cleaned_data['ids']
# Prints [u'1', u'2']
return super(MyView, self).form_valid(form)
def get_form_kwargs(self):
form_kwargs = super(MyView, self).get_form_kwargs()
query = Image.objects.all().values_list('id', flat=True)
form_kwargs['image_ids'] = [(image_id, image_id) for image_id in query]
return form_kwargs
And a sample form:
class MyForm(forms.Form):
# This might be better as a ModelChoiecField
ids = forms.MultipleChoiceField()#
def __init__(self, image_ids, *args, **kwargs):
super(MyForm, self).__init__(*args, **kwargs)
self.fields['ids'].choices = image_ids
Upvotes: 3