<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                # 管理操作 簡而言之,Django管理后臺的基本流程是,“選擇一個對象并改變它”。在大多數情況下,這是非常適合的。然而當你一次性要對多個對象做相同的改變,這個流程是非常的單調乏味的。 在這些例子中,Django管理后臺可以讓你實現和注冊“操作” —— 僅僅只是一個以已選中對象集合為參數的回調函數。 在Django自帶的管理頁面中都能看到這樣的例子。Django在所有的模型中自帶了一個“刪除所選對象”操作。例如,下面是 [`django.contrib.auth`](../../../topics/auth/index.html#module-django.contrib.auth) app 在Django's創建的用戶模型: ![../../../_images/user_actions.png](https://docs.djangoproject.com/en/1.8/_images/user_actions.png) 警告 “刪除所選對象”的操作由于性能因素使用了[`QuerySet.delete()`](../../models/querysets.html#django.db.models.query.QuerySet.delete),這里有個附加說明:它不會調用你模型的`delete()`方法。 如果你想覆寫這一行為,編寫自定義操作,以你的方式實現刪除就可以了 -- 例如,對每個已選擇的元素調用`Model.delete()`。 關于整體刪除的更多信息,參見[_對象刪除_](../../../topics/db/queries.html#topics-db-queries-delete)的文檔。 繼續閱讀,來弄清楚如何向列表添加你自己的操作。 ## 編寫操作 通過示例來解釋操作最為簡單,讓我們開始吧。 操作的一個最為普遍的用例是模型的整體更新。考慮帶有`Article`模型的簡單新聞應用: ``` from django.db import models STATUS_CHOICES = ( ('d', 'Draft'), ('p', 'Published'), ('w', 'Withdrawn'), ) class Article(models.Model): title = models.CharField(max_length=100) body = models.TextField() status = models.CharField(max_length=1, choices=STATUS_CHOICES) def __str__(self): # __unicode__ on Python 2 return self.title ``` 我們可能在模型上執行的一個普遍任務是,將文章狀態從“草稿”更新為“已發布”。我們在后臺一次處理一篇文章非常輕松,但是如果我們想要批量發布一些文章,會非常麻煩。所以讓我們編寫一個操作,可以讓我們將一篇文章的狀態修改為“已發布”。 ### 編寫操作 函數 首先,我們需要定義一個函數,當后臺操作被點擊觸發的時候調用。操作函數,跟普通的函數一樣,需要接收三個參數: * 當前的 [`ModelAdmin`](index.html#django.contrib.admin.ModelAdmin "django.contrib.admin.ModelAdmin") * 表示當前請求的[`HttpRequest`](../../request-response.html#django.http.HttpRequest "django.http.HttpRequest") * 含有用戶所選的對象集合的[`QuerySet`](../../models/querysets.html#django.db.models.query.QuerySet "django.db.models.query.QuerySet") 我們用于發布這些文章的函數并不需要[`ModelAdmin`](index.html#django.contrib.admin.ModelAdmin "django.contrib.admin.ModelAdmin")或者請求對象,但是我們會用到查詢集: ``` def make_published(modeladmin, request, queryset): queryset.update(status='p') ``` 注意 為了性能最優,我們使用查詢集的[_update 方法_](../../../topics/db/queries.html#topics-db-queries-update)。其它類型的操作可能需要分別處理每個對象;這種情況下我們需要對查詢集進行遍歷: ``` for obj in queryset: do_something_with(obj) ``` 編寫操作的全部內容實際上就這么多了。但是,我們要進行一個可選但是有用的步驟,在后臺給操作起一個“非常棒”的標題。通常,操作以“Make published”的方式出現在操作列表中 -- 所有空格被下劃線替換后的函數名稱。這樣就很好了,但是我們可以提供一個更好、更人性化的名稱,通過向`make_published`函數添加`short_description` 屬性: ``` def make_published(modeladmin, request, queryset): queryset.update(status='p') make_published.short_description = "Mark selected stories as published" ``` 注意 這看起來可能會有點熟悉;admin的`list_display`選項使用同樣的技巧,為這里注冊的回掉函數來提供人類可讀的描述。 ### 添加操作到 [`ModelAdmin`](index.html#django.contrib.admin.ModelAdmin) 接下來,我們需要把操作告訴[`ModelAdmin`](index.html#django.contrib.admin.ModelAdmin)。它和其他配置項的工作方式相同。所以,帶有操作及其注冊的完整的`admin.py`看起來像這樣: ``` from django.contrib import admin from myapp.models import Article def make_published(modeladmin, request, queryset): queryset.update(status='p') make_published.short_description = "Mark selected stories as published" class ArticleAdmin(admin.ModelAdmin): list_display = ['title', 'status'] ordering = ['title'] actions = [make_published] admin.site.register(Article, ArticleAdmin) ``` 這段代碼會向我們提供admin的更改列表,看起來像這樣: ![../../../_images/article_actions.png](https://docs.djangoproject.com/en/1.8/_images/article_actions.png) 這就是全部內容了。如果你想編寫自己的操作,你現在應該知道怎么開始了。這篇文檔的剩余部分會介紹更多高級技巧。 ### 在操作中處理錯誤 如果你預見到,運行你的操作時可能出現一些錯誤,你應該以優雅的方式向用戶通知這些錯誤。也就是說,異常處理和使用[`django.contrib.admin.ModelAdmin.message_user()`](index.html#django.contrib.admin.ModelAdmin.message_user)可以在響應中展示用戶友好的問題描述。 ## 操作的高級技巧 對于進一步的選擇,你可以使用一些額外的選項。 ### ModelAdmin上的操作&nbsp;[`ModelAdmin`](index.html#django.contrib.admin.ModelAdmin) 上面的例子展示了定義為一個簡單函數的`make_published`操作。這真是極好的,但是以視圖的代碼設計角度來看,它并不完美:由于操作與`Article`緊密耦合,不如將操作直接綁定到`ArticleAdmin`對象上更有意義。 這樣做十分簡單: ``` class ArticleAdmin(admin.ModelAdmin): ... actions = ['make_published'] def make_published(self, request, queryset): queryset.update(status='p') make_published.short_description = "Mark selected stories as published" ``` 首先注意,我們將`make_published`放到一個方法中,并重命名&nbsp;`modeladmin`&nbsp;為`self`,其次,我們現在將`'make_published'`字符串放進了`actions`,而不是一個直接的函數引用。這樣會讓&nbsp;[`ModelAdmin`](index.html#django.contrib.admin.ModelAdmin)將這個操作視為方法。 將操作定義為方法,可以使操作以更加直接、符合語言習慣的方式來訪問[`ModelAdmin`](index.html#django.contrib.admin.ModelAdmin),調用任何admin提供的方法。 例如,我們可以使用`self`來向用戶發送消息,告訴她操作成功了: ``` class ArticleAdmin(admin.ModelAdmin): ... def make_published(self, request, queryset): rows_updated = queryset.update(status='p') if rows_updated == 1: message_bit = "1 story was" else: message_bit = "%s stories were" % rows_updated self.message_user(request, "%s successfully marked as published." % message_bit) ``` 這會使動作與后臺在成功執行動作后做的事情相匹配: ![../../../_images/article_actions_message.png](https://docs.djangoproject.com/en/1.8/_images/article_actions_message.png) ### 提供中間頁面的操作 通常,在執行操作之后,用戶會簡單地通過重定向返回到之前的修改列表頁面中。然而,一些操作,尤其是更加復雜的操作,需要返回一個中間頁面。例如,內建的刪除操作,在刪除選中對象之前需要向用戶詢問來確認。 要提供中間頁面,只要從你的操作返回[`HttpResponse`](../../request-response.html#django.http.HttpResponse)(或其子類)就可以了。例如,你可能編寫了一個簡單的導出函數,它使用了Django的[_序列化函數_](../../../topics/serialization.html)來將一些選中的對象轉換為JSON: ``` from django.http import HttpResponse from django.core import serializers def export_as_json(modeladmin, request, queryset): response = HttpResponse(content_type="application/json") serializers.serialize("json", queryset, stream=response) return response ``` 通常,上面的代碼的實現方式并不是很好。大多數情況下,最佳實踐是返回&nbsp;[`HttpResponseRedirect`](../../request-response.html#django.http.HttpResponseRedirect),并且使用戶重定向到你編寫的視圖中,向GET查詢字符串傳遞選中對象的列表。這需要你在中間界面上提供復雜的交互邏輯。例如,如果你打算提供一個更加復雜的導出函數,你會希望讓用戶選擇一種格式,以及可能在導出中包含一個含有字段的列表。最佳方式是編寫一個小型的操作,簡單重定向到你的自定義導出視圖中: ``` from django.contrib import admin from django.contrib.contenttypes.models import ContentType from django.http import HttpResponseRedirect def export_selected_objects(modeladmin, request, queryset): selected = request.POST.getlist(admin.ACTION_CHECKBOX_NAME) ct = ContentType.objects.get_for_model(queryset.model) return HttpResponseRedirect("/export/?ct=%s&ids=%s" % (ct.pk, ",".join(selected))) ``` 就像你看到的那樣,這個操作是最簡單的部分;所有復雜的邏輯都在你的導出視圖里面。這需要處理任何類型的對象,所以需要處理`ContentType`。 這個視圖的編寫作為一個練習留給讀者。 ### 在整個站點應用操作 `AdminSite.``add_action`(_action_[, _name_]) 如果一些操作對管理站點的_任何_對象都可用的話,是非常不錯的 -- 上面所定義的導出操作是個不錯的備選方案。你可以使用[`AdminSite.add_action()`](#django.contrib.admin.AdminSite.add_action)讓一個操作在全局都可以使用。例如: ``` from django.contrib import admin admin.site.add_action(export_selected_objects) ``` 這樣,`export_selected_objects` 操作可以在全局使用,名稱為“export_selected_objects”。你也可以顯式指定操作的名稱 – 如果你想以編程的方式[_移除這個操作_](#disabling-admin-actions) – 通過向[`AdminSite.add_action()`](#django.contrib.admin.AdminSite.add_action)傳遞第二個參數: ``` admin.site.add_action(export_selected_objects, 'export_selected') ``` ### 禁用操作 有時你需要禁用特定的操作 -- 尤其是[_注冊的站點級操作_](#adminsite-actions) -- 對于特定的對象。你可以使用一些方法來禁用操作: #### 禁用整個站點的操作 `AdminSite.``disable_action`(_name_) 如果你需要禁用[_站點級操作_](#adminsite-actions) ,你可以調用 [`AdminSite.disable_action()`](#django.contrib.admin.AdminSite.disable_action)。 例如,你可以使用這個方法來移除內建的“刪除選中的對象”操作: ``` admin.site.disable_action('delete_selected') ``` 一旦你執行了上面的代碼,這個操作不再對整個站點中可用。 然而,如果你需要為特定的模型重新啟動在全局禁用的對象,把它顯式放在`ModelAdmin.actions` 列表中就可以了: ``` # Globally disable delete selected admin.site.disable_action('delete_selected') # This ModelAdmin will not have delete_selected available class SomeModelAdmin(admin.ModelAdmin): actions = ['some_other_action'] ... # This one will class AnotherModelAdmin(admin.ModelAdmin): actions = ['delete_selected', 'a_third_action'] ... ``` #### 為特定的ModelAdmin禁用所有操作&nbsp;[`ModelAdmin`](index.html#django.contrib.admin.ModelAdmin) 如果你想批量_移除_所提供&nbsp;[`ModelAdmin`](index.html#django.contrib.admin.ModelAdmin)上的所有操作,可以把[`ModelAdmin.actions`](index.html#django.contrib.admin.ModelAdmin.actions)設置為`None`: ``` class MyModelAdmin(admin.ModelAdmin): actions = None ``` 這樣會告訴[`ModelAdmin`](index.html#django.contrib.admin.ModelAdmin ),不要展示或者允許任何操作,包括[_站點級操作_](#adminsite-actions)。 #### 按需啟用或禁用操作 `ModelAdmin.``get_actions`(_request_) 最后,你可以通過覆寫[`ModelAdmin.get_actions()`](#django.contrib.admin.ModelAdmin.get_actions),對每個請求(每個用戶)按需開啟或禁用操作。 這個函數返回包含允許操作的字典。字典的鍵是操作的名稱,值是&nbsp;`(function, name, short_description)`元組。 多數情況下,你會按需使用這一方法,來從超類中的列表移除操作。例如,如果我只希望名稱以'J'開頭的用戶可以批量刪除對象,我可以執行下面的代碼: ``` class MyModelAdmin(admin.ModelAdmin): ... def get_actions(self, request): actions = super(MyModelAdmin, self).get_actions(request) if request.user.username[0].upper() != 'J': if 'delete_selected' in actions: del actions['delete_selected'] return actions ``` > 譯者:[Django 文檔協作翻譯小組](http://python.usyiyi.cn/django/index.html),原文:[Admin actions](https://docs.djangoproject.com/en/1.8/ref/contrib/admin/actions/)。 > > 本文以 [CC BY-NC-SA 3.0](http://creativecommons.org/licenses/by-nc-sa/3.0/cn/) 協議發布,轉載請保留作者署名和文章出處。 > > [Django 文檔協作翻譯小組](http://python.usyiyi.cn/django/index.html)人手緊缺,有興趣的朋友可以加入我們,完全公益性質。交流群:467338606。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看