2013-11-15 22 views
11

我需要附加一個用戶到一個請求,這似乎是一個相當普遍的事情需要做的,但它變成該死的幾乎不可能。Django REST Framework,pre_save()和serializer.is_valid(),它們是如何工作的?

Django REST Framework的文檔建議使用序列化器類的pre_save方法,但我在調用serializer.is_valid()時沒有調用它,這使得它沒有價值,因爲沒有序列化程序的用戶字段未通過驗證。

我見過一些建議,但他們似乎是瘋狂的黑客和/或不工作。另外,我覺得這是一個太常見的任務,真的需要我看到人們建議的所有東西。我不能是唯一需要將用戶附加到在REST請求中創建的對象的人。

+2

FYI關於這個問題[GitHub上提出](https://github.com/tomchristie/django-rest-framework/issues/821),但我不認爲解決方案已經完成。 –

回答

2

原來問題是我使用ListAPIView作爲我的視圖類的基類,它沒有定義pre_save方法當我添加了一些它定義了所有的mixin開始工作。

看起來很奇怪,很多基本教程中使用的東西不支持這樣的基本功能,而是生活和學習。

+0

你是如何將調用添加到序列化程序中的'pre_save'的? – Alp

+0

我沒有,事實證明pre_save是在視圖mixins中定義的,所以我在視圖中處理了這個,而不是序列化器。雖然我懷疑ListAPIView使用pre_save,因爲它是隻讀的。 – jmickela

+0

感謝您的回答。你有權訪問視圖pre_save方法中的序列化數據嗎?或者我們是否應該使用原始的REQUEST數據? – Alp

5

假設你正在使用(或Django的驗證)這裏所描述的身份驗證機制之一:

http://django-rest-framework.org/api-guide/authentication.html,你有一個

request.user對象。

當您創建序列化程序時,將其從請求中拉出/在實例化時將其傳入。

MySerializer(data={"user": request.user, "otherField"=... }) 

如果你正在做的:

MySerializer(data=request.DATA) 

你需要複製request.DATA對象:

from django.utils.datastructures import MultiValueDict 
... 
data = MultiValueDict(request.DATA) 
data['user'] = request.user 
MySerializer(data=data) 
3

pre_saveis_valid後調用,但之前的實例保存到數據庫。你需要重寫驗證(對用戶串行場使用def get_validation_exclusions(self):因爲你在pre_save解決驗證問題在這裏看到我以前的答案:

Django REST Framework serializer field required=false

我加註到DRF的作者和他們正在研究一個更可行的解決方案

1

此問題的最佳解決方案是標記填充在序列化程序中的pre_saveread_only_fields所需的字段。

要做到這一點,添加以下到串行化類:

class MySerializer(serializers.ModelSerializer): 
    ... 
    class Meta: 
     ... 
     read_only_fields = ['user', 'my_other_field', ...] 
1

在DRF(3.X)的新版本,pre_save改爲 perform_createperform_updateReference

相關問題