Custom Search

Thursday, August 21, 2014

Django ModelAdmin Action Passing multiple parameters

Django ModelAdmin Delete action Passing multiple parameters

* Override the method "action_checkbox" of "admin.ModelAdmin" to pass multiple values from the Form via POST request when submitting the Form. In this example, I am creating string like "4|130476|2012" (bookid|userid|year), which contains the items required to construct the delete query.

* Override the method "changelist_view" of "admin.ModelAdmin" to parse the original unique id from the sting "4|130476|2012" (bookid|userid|year), and pass to "changelist_view" of "admin.ModelAdmin". So other things will work fine.

* Add "delete_selected" in class variable "actions"

* Then Create a method named "deleted_selected" and write a delete query there to delete the object based on multiple values.

* In this example, I am modifying request.POST[admin.ACTION_CHECKBOX_NAME] and creating new item request.POST[admin.ACTION_CHECKBOX_NAME+"_"] in request.POST.

class StatusAdmin(admin.ModelAdmin):

     actions = ['delete_selected']

    def delete_selected(self, request, obj):
        ##* See django/contrib/admin/options.py and django/contrib/admin/helpers.py
        ##use our custom action checkbox value "4|130476|2012" (bookid|userid|year) to delete entry from "userbookstatus" table.
        _selected_action_ = request.POST.getlist(admin.ACTION_CHECKBOX_NAME + "_")
        if _selected_action_:
            del_items = [{"book_id":x.split("|")[0], "user_id":x.split("|")[1], "year":x.split("|")[2]} for x in _selected_action_[0]]
            cursor = connection.cursor()
            for del_item in del_items:
                cursor.execute("delete from userbookstatus where indexbookid='%s' and year='%s' and userid='%s'"\
                            %(del_item["book_id"], del_item["year"], del_item["user_id"]))
            transaction.commit_unless_managed()
            self.message_user(request, "Deleted %s UserBooks" % (len(del_items)))

    def action_checkbox(self, obj):
        """
        A list_display column containing a checkbox widget.
        """
        ###* See django/contrib/admin/options.py and django/contrib/admin/helpers.py
        ###Create a custom value like "4|130476|2012" (bookid|userid|year) and save it in value field of action checkbox
        return helpers.checkbox.render(helpers.ACTION_CHECKBOX_NAME, force_text(obj.pk) + "|" + force_text(obj.user.id) + "|" + str(obj.year))
   
    ##* See django/contrib/admin/options.py and django/contrib/admin/helpers.py
    ##remove title of action checkbox
    action_checkbox.short_description = mark_safe('')
    action_checkbox.allow_tags = True

    def changelist_view(self, request, extra_context=None):
        # Actions with no confirmation
        actions = self.get_actions(request)
        if (actions and request.method == 'POST' and
                'index' in request.POST and '_save' not in request.POST):
            selected = request.POST.getlist(helpers.ACTION_CHECKBOX_NAME)
            if selected:
                ##Save/backup our custom action checkbox value "4|130476|2012" (bookid|userid|year) in another temporary location of request.POST
                request.POST[admin.ACTION_CHECKBOX_NAME+"_"] = selected
                ##Restore the original value of action checkbox to request.POST, So existing code will work fine.
                request.POST[admin.ACTION_CHECKBOX_NAME] = [x.split("|")[0] for x in selected][0]
        return super(StatusAdmin, self).changelist_view(request, extra_context)




No comments:

Post a Comment