When user visits "baseurl/companies/6/inquiry/", I know that the company_id is 6.
Then user then has the option to create an inquiry with specific products, but should only see the products that belong to company 6.
Here's my viewset:
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)
Here's my serializer:
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')
And here's the 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)
There has to be a simple way I can access the company_id that's already in InquirySerializer's init method and just pass that on, but I'm stumped.
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)
The self.root
attribute on the CompanyProductField class will refer to the instance of InquirySerializer in this case.
For now, I'm going to use this somewhat "hacky" way of doing this.
In my serializers.py file I added a global variable:
from rest_framework import serializers
from .models import *
from django.db.models import Q
global_company_id = 0
Then in the init method for my serializer I set the global_company_id:
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)
And in the CompanyProductField I accessed the 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)
You could just remove the self
from self.kwargs['company_id'] in your
get_serializer()` method,
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)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.