2012-07-16 60 views
4

是否有可能在連接到pre_delete信號的回調中獲得登錄的django用戶(即調用模型的刪除方法)?django中的pre_delete信號中的當前用戶

+0

你可能不得不去與treadlocal的做法,但也有可能根據你試圖達到的目標,更好地解決你的問題,換句話說,你需要提供更多有關你的問題背景的信息。 – 2012-07-16 08:56:07

+0

後端數據庫中有一個on-delete觸發器,用於在某些表中存儲關於已刪除信息的on-delete觸發器記錄在其他表格中。我需要誰(哪個django用戶)啓動刪除操作的信息,所以我試圖使用一種方法,用django-user id更新要刪除的記錄,這樣用戶就可以用於觸發器。 – 2012-07-16 09:38:12

回答

5

pre_delete信號沒有通過請求實例,但是您可以添加一個裝飾器,添加它並在視圖上使用該裝飾器,這會刪除指定的模型。

假設這是回調函數:這是在裝飾添加

def pre_delete_cb(sender, instance, using, **kwargs): 
    pass 

from django.db.models.signals import pre_delete 
from functools import wraps 
from django.utils.decorators import available_attrs 

def pre_delete_dec(cb, sender): 
    def decorator(view_func): 
     @wraps(view_func, assigned=available_attrs(view_func)) 
     def _wrapped_view(request, *args, **kwargs): 
      cb.request = request # here we add the request to the callback function 
      pre_delete.connect(cb, sender=sender) # and connecting the real pre_delete to the callback 
      return view_func(request, *args, **kwargs) 
     return _wrapped_view 
    return decorator 

並使用在你打電話的方式視圖的裝飾 - 而不是pre_delete.connect(pre_delete_cb, MyModel),使用:

@pre_delete_dec(pre_delete_cb, MyModel) 
def myview(request): 

然後在回調中,您將有權訪問t Ø請求爲:

def pre_delete_cb(sender, instance, using, **kwargs): 
    current_user = pre_delete_cb.request.user 

您可以在全球範圍添加此,不只是每個視圖 - 使用中間件:

from django.db.models.signals import pre_delete 

def pre_delete_cb(sender, instance, using, **kwargs): 
    current_user = pre_delete_cb.request.user 

class PreDeleteMiddleware(object): 
    def process_view(self, request, view_func, view_args, view_kwargs): 
     pre_delete_cb.request = request 
     from myapp.models import MyModel 
     pre_delete.connect(pre_delete_cb, sender=MyModel) 
+0

是否有可能爲幾種模型創建更通用的解決方案?在您的解決方案中,如果我理解正確,則必須爲每個模型單獨裝飾每個視圖。 – 2012-07-17 09:27:24

+0

當然,使用中間件。只需刪除PreDeleteMiddleware的最後2行,並將它們添加到代碼中的某處,無論您喜歡什麼模式。只需在'pre_delete.connect(pre_delete_cb,sender = some_model)'中使用pre_delete_cb回調方法。中間件的確與真實模型無關。它只需要將請求屬性設置爲回調函數。但是你也可以使用裝飾器 - 將pre_delete.connect移出它。它只需要請求對象和回調。 – Tisho 2012-07-17 10:36:39