Models:
class MaterialRequest(models.Model):
owner = models.ForeignKey(User, on_delete=models.CASCADE, related_name='owner')
linked = models.CharField(max_length=50, default="-", blank=True, null=True)
flows = models.ManyToManyField(MaterialRequestFlow)
is_allocated = models.BooleanField(default=False)
delivery_required_on = models.DateTimeField(default=datetime.now)
raised_by = models.CharField(max_length=1000, default="__________", blank=True, null=True)
created_at = models.DateTimeField(auto_now_add=True)
class Allotment(models.Model):
transaction_no = models.IntegerField(default=0)
sales_order = models.ForeignKey(MaterialRequest, on_delete=models.CASCADE)
is_delivered = models.BooleanField(default=False)
document_available = models.BooleanField(default=False)
Now to show my Material Request table I am doing something like this:
class MREmpTableAPIView(APIView):
permission_classes = (permissions.IsAuthenticated, MRViewPermission)
def get(self, request, *args, **kwargs):
items = MaterialRequest.objects.all().order_by('-id')
serializer = EMaterialRequestTableListSerializer(items, many=True)
return Response(serializer.data, status=status.HTTP_201_CREATED)
Serializer:
class EMaterialRequestTableListSerializer(serializers.ModelSerializer):
owner = serializers.SlugRelatedField(read_only=True, slug_field='full_name')
class Meta:
model = MaterialRequest
exclude = ('flows',)
Where I get all the detaila of Material Requests but I also want to show the transaction_no of the linked Allotment in Material Request Table. How do I do that?
Edit:
A single Material Request is linked with a single allotment(transaction_no), I want to show the Transaction no on the same table
Output I am getting:
created_at: "2021-09-22T10:28:44.248034Z"
delivery_required_on: "2021-09-22T09:08:43.968000Z"
id: 739
is_allocated: false
linked: "729-3"
owner: "Lumax Mannoh Allied Technologies Limited"
Desired Output:
created_at: "2021-09-22T10:28:44.248034Z"
delivery_required_on: "2021-09-22T09:08:43.968000Z"
id: 739
is_allocated: false
linked: "729-3"
owner: "Lumax Mannoh Allied Technologies Limited"
transaction_no: foo
A straightforward way to solve this is to use a SerializerMethodField like this:
class EMaterialRequestTableListSerializer(serializers.ModelSerializer):
owner = serializers.SlugRelatedField(read_only=True, slug_field='full_name')
transaction_no = serializers.SerializerMethodField()
class Meta:
model = MaterialRequest
exclude = ('flows',)
def get_transaction_no(self, obj)
allotment = obj.allotment_set.first()
return allotment.transaction_no if allotment else None
But this will try to hit the database per MaterialRequest instance just to get the related allotments.
To make this more efficient, you can prefetch the related allotments of each material request like this:
items = MaterialRequest.objects.all().order_by('-id').prefetch_related('allotment_set')
And then do something like this in your serializer:
class EMaterialRequestTableListSerializer(serializers.ModelSerializer):
owner = serializers.SlugRelatedField(read_only=True, slug_field='full_name')
transaction_no = serializers.SerializerMethodField()
class Meta:
model = MaterialRequest
exclude = ('flows',)
def get_transaction_no(self, obj)
if obj.allotment_set.all():
return obj.allotment_set.all()[0].transaction_no
return None
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With