![](/img/trans.png)
[英]How to make a field of a model form read-only when a certain field of an instance is True (Django)?
[英]How to make a model instance read-only after saving it once?
我正在編寫的Django項目的功能之一就是發送新聞通訊。 我有一個模型Newsletter
和一個函數send_newsletter
,我已經注冊了該模型以收聽Newsletter
的post_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消失,如果
has_change_permission
返回False甚至不會禁用表單 admin_modify.submit_row
模板admin_modify.submit_row
),將無條件使用show_save=True
。 無論如何,一種使該人不被渲染的方法是:
使用適當的邏輯創建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)
覆蓋類似於以下內容的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.