簡體   English   中英

保存一次后如何使模型實例為只讀?

[英]How to make a model instance read-only after saving it once?

我正在編寫的Django項目的功能之一就是發送新聞通訊。 我有一個模型Newsletter和一個函數send_newsletter ,我已經注冊了該模型以收聽Newsletterpost_save信號。 通過管理員界面保存新聞稿對象時, send_newsletter檢查是否created為True,如果是,則實際上會發送郵件。

但是,出於顯而易見的原因,編輯已發送的新聞通訊沒有太大意義。 保存Newsletter對象是否有使其只讀的方法?

編輯:

我知道我可以覆蓋對象的save方法來引發錯誤,或者如果對象存在則別無所求。 但是,我認為這樣做沒有意義。 至於前者,我不知道在哪里捕獲該錯誤以及如何向用戶傳達未保存對象的事實。 至於后者,給用戶錯誤的反饋(管理界面說保存成功)似乎不是一件好事。

我真正想要的是允許用戶使用Admin界面編寫新聞稿並將其發送,然后瀏覽已發送的新聞稿。 我希望管理界面在不可編輯的輸入框中顯示發送的新聞通訊的數據,而無需“保存”按鈕。 另外,我希望“保存”按鈕處於非活動狀態。

您可以在模型的save方法中檢查它是創建還是更新:

def save(self, *args, **kwargs):
    if self.pk:
        raise StandardError('Can\'t modify bla bla bla.')
    super(Payment, self).save(*args, **kwargs)

如果您嘗試保存現有對象,則上面的代碼將引發異常。 先前未持久保存的對象沒有設置主鍵。

建議閱讀: Django Book第17章中的Admin Zen。

摘要:管理員不是針對您要執行的操作而設計的:(

但是,該書的1.0版僅涵蓋Django 0.96,此后發生了很多事情。

在Django 1.0中, 管理站點更具可定制性。 由於我自己還沒有自定義管理員,因此我不得不根據文檔進行猜測,但是我想說, 覆蓋模型形式是最好的選擇。

您可以輕松地將所有字段設置為只讀:

class MyModelAdmin(ModelAdmin):
    form = ...
    def get_readonly_fields(self, request, obj=None):
        if obj:
            return MyModelAdmin.form.Meta.fields
        else: # This is an addition
            return []

至於使Save消失,如果

  1. has_change_permission返回False甚至不會禁用表單
  2. 負責呈現管理表單控件的代碼段( admin_modify.submit_row模板admin_modify.submit_row ),將無條件使用show_save=True

無論如何,一種使該人不被渲染的方法是:

  1. 使用適當的邏輯創建has_change_permission的替代版本:

     class NoSaveModelAdminMixin(object): def render_change_form(self, request, context, add=False, change=False, form_url='', obj=None): response = super(NoSaveModelAdmin, self).render_change_form(request, context, add, change,form_url, obj) response.context_data["has_change_permission"] = self.has_real_change_permission(request, obj) def has_real_change_permission(self, request, obj): return obj==None def change_view(self, request, object_id, extra_context=None): obj = self.get_object(request, unquote(object_id)) if not self.has_real_change_permission(request, obj) and request.method == 'POST': raise PermissionDenied return super(NoSaveModelAdmin, self).change_view(request, object_id, extra_context=extra_context) 
  2. 覆蓋類似於以下內容的submit_row模板標簽:

     @admin_modify.register.inclusion_tag('admin/submit_line.html', takes_context=True) def submit_row(context): ... 'show_save': context['has_change_permission'] ... admin_modify.submit_row = submit_row 

在ur amdin.py中使用readonlyadmin。列出您要設為只讀的所有字段。創建對象后,可以對其進行編輯,然后

使用鏈接

http://www.djangosnippets.org/snippets/937/

復制文件,然后導入ur admin.py並使用它

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM