2016-08-25 154 views
0

我有一個關於泛型關係的django rest框架的一個小問題,它也被用在unique_together約束中。django rest框架:contenttype unique_together和序列化

我有這樣的模式:

class VPC(models.Model): 
    name = models.SlugField(null=False, max_length=100) 
    deletable = models.BooleanField(null=False, default=True) 
    date_created = models.DateTimeField(auto_now_add=True) 
    date_modified = models.DateTimeField(auto_now=True) 
    content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE) 
    object_id = models.PositiveIntegerField() 
    content_object = GenericForeignKey('content_type', 'object_id') 

    class Meta: 
     unique_together = (('name', 'content_type', 'object_id')) 

它有一個通用的關係,唯一約束:在VPC +通用的關係(也就是所有者)的名稱。

這裏是串行:

class VPCSerializer(serializers.ModelSerializer): 

class Meta: 
    model = VPC 
    read_only_fields = ('deletable', 'date_created', 'date_modified') 
    fields = ('name', 'deletable') 
    lookup_field = 'name' 
    validators = [ 
     UniqueTogetherValidator(
      queryset=VPC.objects.all(), 
      fields=('name', 'content_type', 'object_id') 
     ) 
    ] 

在田間地頭,我不把CONTENT_TYPE和OBJECT_ID,因爲我不想讓他們來顯示/由用戶設定。

但是我必須將它們放入UniqueTogetherValidator以避免創建具有相同帳戶/名稱的VPC時引發的django.db.utils.integrityerror錯誤。

但現在,當我嘗試創建一個VPC我得到這個錯誤:

{「OBJECT_ID」:「這是必須填寫」],「CONTENT_TYPE」:「這是必須填寫。 「]}

所以在我viewsets.ModelViewSet我試圖重寫perform_create() 設置OBJECT_IDCONTENT_TYPE BU它看起來像調用此方法之前引發的錯誤。

我也嘗試覆蓋get_serializer_context()返回包含object_id和content_type的字典,但它也不工作。

我花了很多時間在這個,我沒有找到。 那麼我應該重寫哪些方法才能在序列化程序中設置object_id和content_type?

謝謝。

回答

0

串行器驗證發生在

def create(self, request, *args, **kwargs): 

方法不是在「perform_create」

你需要重寫「創造」的方法,並填寫「CONTENT_TYPE」,「OBJECT_ID」的請求數據(這將用於初始化串行器和驗證)。

,你可以這樣做,例如,

def create(self, request, *args, **kwargs): 
    if hasattr(request.data, '_mutable'): 
     request.data._mutable = True 
    request.data['content_type'] = "your_content_type" 
    request.data['content_type'] = "your_object_id" 

    serializer = VPCSerializer(data=request.data, request=request) 
    serializer.is_valid(raise_exception=True) 
    self.perform_create(serializer) 

    return Response here.. 

只需填寫所需的數據初始化串行之前,檢查驗證,然後保存使用串行對象,並返回serilizer.data或定製任何您迴應想。

+0

非常感謝,它的工作原理! (注意:將字段屬性的content_type和object_id添加到序列化程序中) – JonDeau

相關問題