2009-12-29 84 views
3

我正在考慮在管理員之外創建類似管理員操作的行爲。因此,用戶應該能夠使用複選框來選擇對象,並且在選擇具有下拉的動作之後,對所有選擇的對象執行所選動作。創建django管理員喜歡非管理員前端用戶的操作 - 如何

我想到了以下方法。

爲.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函數,它接受請求,並將在採取行動的模式。從post querydicts我得到了選擇的動作(request.POST。getitem('action'))和選中的對象(r​​equest.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(請求,模型,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不同的觀點和封裝從模型刪除功能的影響無關函數在其上作用。

+0

@ S.Lott 哦對不起。我習慣於把所有的東西寫成「全部小寫」的風格。會改變它。 – 2009-12-29 15:35:47

+0

@tomtom:不要道歉。只需修復它。英語世界的其餘部分使用大寫字母。你應該適應傳統的使用方式。 – 2009-12-30 19:07:09

回答

2

這是一個動態形式的理想場所。總的想法是製作一個表格,其中列出了所有的項目和用戶的下拉菜單。所以這很容易映射到ModelMultipleChoiceFieldChoiceField

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 ... 

然後,只需像顯示任何其他模板一樣顯示此表單。希望有所幫助。

+0

看起來不錯。我明天會試一試。 – 2009-12-29 23:06:03

+0

運氣好嗎? – JudoWill 2009-12-31 00:16:55

+0

其實我沒有嘗試過,因爲我有另一個想法它可以如何工作。看到我上面的解決方案這對我有用。我對django很陌生,我一見鍾情就沒有得到這個動態形式的想法。我正在使用基於模型的表單。我認爲你的表單工廠是個好主意。但是當我需要基於模型的表單時,我認爲它不適合。你怎麼看? – 2009-12-31 00:26:40