Reputation: 1390
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.
Upvotes: 3
Views: 965
Reputation: 8026
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.
Upvotes: 2
Reputation: 9245
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)
Upvotes: 0
Reputation: 1390
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)
Upvotes: 1