为非管理员前端用户创建类似 django 管理员的操作 - 如何

2024-01-15

我正在考虑在管理员之外创建类似管理操作的行为。因此,用户应该能够使用复选框选择对象,并且在使用下拉列表选择操作后,将对所有选定的对象执行所选操作。

我想到了以下方法。

为 .html 模板中的每个对象创建一个复选框。结果是这样的(我从管理员那里得到的):

<td><input type="checkbox" class="action-select" value="24" name="_selected_action" /></td> 

然后创建操作下拉列表(也从管理员处获取):

<div class="actions"> 
            <label>Action: <select name="action"> 
                <option value="" selected="selected">---------</option> 
                <option value="delete_selected">Delete selected contacts</option> 
            </select></label> 
            <button type="submit" class="button" title="Run the selected action" name="index" value="0">Go</button> 
        </div> 

现在我问自己如何将这个操作下拉列表映射到 python 函数。可能是我将放置在我想要应用此操作的模型对象内的函数。

我希望有人能告诉我。

下一点是我如何在此功能中检查已选择哪些对象。 当我发现它是如何工作的时,我可以使用这个对象并返回一个 HttpResponse。

我认为这应该是创造类似行为的一切。这是正确的还是缺少什​​么?

编辑:我的解决方案

最后我想出了以下解决方案:

我创建了一个名为 action_handler 的函数,它接受请求和它将执行的模型。从帖子查询字典中,我获得了选定的操作(request.POST.getitem('action')) 和选定的对象 (request.POST.getlist('_selected_for_action'))。

根据输入和过程,函数返回一些值,这些值告诉调用视图在action_handler 中发生了什么。

@login_required
def action_handler(request, model):
    """
    PARAMETERS
    model = the django model upon which the actions are executed

    RETURN VALUES
    0 - POST param action is not available
      - POST param selected_action is not defined
      - selected_ids is empty
      - object_list is empty
    1 - Successfully conducted the delete_selected action
    2 - Successfully conducted the new_selection action

    DESCRIPTION
    handles all actions for arbitrary models
    Action:
        "delete selected" - calls the generic delete method, delete_objects(request, model, selected_ids)
    """
    try:
        selected_action = request.POST.__getitem__('action')
        selected_ids = request.POST.getlist('_selected_for_action')
        object_list = model.objects.filter(pk__in=selected_ids)
        if object_list.count() < 1:
            request.user.message_set.create(message='Please select at least one item!')
            return 0
        if selected_action == 'delete_selected':
            try:
                action_approved = request.POST.__getitem__('action_approved')
                if action_approved == '1':
                    delete_objects(request, model, selected_ids)
                    return 1

            except KeyError:
                #action_approved param is not available
                #show the objects check page for delete approval
                context = {
                    'action_name' : selected_action,
                    'object_list' : object_list,
                }
                return render_to_response("crm/object_delete_check.html", context,
                                       context_instance=RequestContext(request))

        if selected_action == 'new_selection':
            #add the selected objects to a new cs selection
            now = datetime.now()
            stamp = now.strftime("%Y-%m-%d/%H:%M")
            cs_name = 'cs_auto_created_' + str(stamp)
            cs = ContactSelection(id=None, name=cs_name)
            cs.created_by = request.user
            cs.save()
            for object in object_list:
                cs.contacts.add(object)
            request.user.message_set.create(message='Successfully created the %s selection' % cs.name)
            return 2

        request.user.message_set.create(message='This action is not available!')
        return 0

    except KeyError:
        request.user.message_set.create(message='Please select an action!')
        return 0

删除delete_objects(request, model, selected_ids)看起来像这样:

@login_required
def delete_objects(request, model, selected_ids):
    '''
    capsulate a bulk delete method
    delete all objects found for the given model
    fails silently since model.delete() always fails silently
    '''
    object_list = model.objects.filter(pk__in=selected_ids)
    count = object_list.count()
    if count == 1:
        name = model._meta.verbose_name.title()
    else:
        name = model._meta.verbose_name_plural.title()
    object_list.delete()
    request.user.message_set.create(message='Successfully deleted %s %s' % (count,name))
    return

这样我就可以为不同的视图包含这个action_handler,并封装一个独立于该函数所作用的模型的删除函数。


这是动态形式的完美场所。总体思路是创建一个表单,向用户列出所有项目以及操作的下拉菜单。所以这很容易映射到ModelMultipleChoiceField and a ChoiceField.

from django import forms

def action_formset(qset, actions):
    """A form factory which returns a form which allows the user to pick a specific action to 
    perform on a chosen subset of items from a queryset.
    """
    class _ActionForm(forms.Form):
        items = forms.ModelMultipleChoiceField(queryset = qset)
        actions = forms.ChoiceField(choices = zip(actions, actions))

    return _ActionForm

#in your views.py

def action_view(request):

    qset = Item.objects.all() #some way to get your items
    actions = ('tuple', 'of', 'action', 'names')

    formclass = action_formset(qset, actions)

    if request.method == 'POST':
        #deal with chosen items
        form = formclass(request.POST)
        chosen_action = form.cleaned_data['action']
        chosen_qset = form.cleaned_data['items']
        #do something with items
        return ...

    #deal with a GET request
    form = formclass()

    return ...

然后只需在模板中显示此表单,就像显示其他表单一样。希望有帮助。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为非管理员前端用户创建类似 django 管理员的操作 - 如何 的相关文章

随机推荐