2017-07-05 87 views
3

當用戶訪問「的BaseURL /公司/ 6 /查詢/」,我知道COMPANY_ID是6Django的REST框架篩選查詢集基於URL

然後用戶就創建具有特定產品的查詢選項,但應該只看到屬於公司6

這裏的產品是我的視圖集:

class InquiryViewSet(viewsets.ModelViewSet): 
    queryset = Inquiry.objects.all() 
    serializer_class = InquirySerializer 

    def get_serializer(self, *args, **kwargs): 
     serializer_class = self.get_serializer_class() 
     context = self.get_serializer_context() 
     return serializer_class(*args, company_id=self.kwargs['company_id'], context=context, **kwargs) 

這裏是我的串行:

class InquirySerializer(serializers.ModelSerializer): 
    def __init__(self, *args, company_id=None, **kwargs): 
     super(InquirySerializer, self).__init__(*args, **kwargs) 
     company_set = Company.objects.filter(pk=company_id) 
     self.fields['company'].queryset = company_set 

    company = serializers.HyperlinkedRelatedField(many=False, 
                view_name='company-detail', 
                queryset=Company.objects.all()) 
    inquirer = UserPKField(many=False) 
    is_anonymous = serializers.BooleanField 
    product_rows = CompanyProductField(many=True, company_id= 'Want to access company_id in __init__') 

    class Meta: 
     model = Inquiry 
     fields = ('pk', 'company', 'inquirer_email', 'inquirer', 'is_anonymous', 'inquiry_date', 'product_rows') 
     read_only_fields = ('inquirer', 'inquiry_date') 

而這裏的CompanyProductField

class CompanyProductField(serializers.PrimaryKeyRelatedField): 
    def __init__(self, *args, company_id=None, **kwargs): 
     super(CompanyProductField, self).__init__(*args, **kwargs) 
     self.company_id = company_id 

    def get_queryset(self): 
     product_query = Q(company__pk=self.company_id) 
     return Product.objects.filter(product_query) 

必須有一個簡單的方法可以讓我訪問是已經在InquirySerializer的初始化方法,只是傳遞的COMPANY_ID,但我很爲難。

回答

2
class InquirySerializer(serializers.ModelSerializer): 
    def __init__(self, *args, **kwargs): 
     company_id = kwargs.pop('company_id') 
     self.company_id = company_id 
     super().__init__(*args, **kwargs) 

    product_rows = CompanyProductField(many=True) 

class CompanyProductField(serializers.PrimaryKeyRelatedField): 
    def get_queryset(self): 
     return Product.objects.filter(company_id=self.root.company_id) 

在CompanyProductField類將指InquirySerializer的實例在這種情況下self.root屬性。

+0

'self.root.company_id'就是我一直在尋找的! –

1

現在,我要用這個有點「哈克」的方式來做到這一點。在我的序列化init方法

from rest_framework import serializers 
from .models import * 
from django.db.models import Q 

global_company_id = 0 

然後我設置global_company_id:

在我serializers.py文件我加了一個全局變量

class InquirySerializer(serializers.ModelSerializer): 
def __init__(self, *args, company_id=None, **kwargs): 
    super(InquirySerializer, self).__init__(*args, **kwargs) 
    company_set = Company.objects.filter(pk=company_id) 
    self.fields['company'].queryset = company_set 
    global global_company_id 
    global_company_id = company_id 

company = serializers.HyperlinkedRelatedField(many=False, 
               view_name='company-detail', 
               queryset=Company.objects.all()) 
inquirer = UserPKField(many=False) 
is_anonymous = serializers.BooleanField 
product_rows = CompanyProductField(many=True) 

而在CompanyProductField我訪問global_company_id:

class CompanyProductField(serializers.PrimaryKeyRelatedField): 
def get_queryset(self): 
    product_query = Q(company__pk=global_company_id) 
    return Product.objects.filter(product_query) 
+0

爲什麼不直接在'product_rows'字段中設置'company_id'屬性,就像在'company'字段中設置查詢集一樣? –

0

您可以從01中刪除 get_serializer()`方法,

def get_serializer(self, *args, **kwargs): 
    serializer_class = self.get_serializer_class() 
    kwargs['context'] = self.get_serializer_context() 
    return serializer_class(company_id=kwargs['company_id'], *args, **kwargs)