0

In my Application I am trying to query a field which in depth requires a reverse lookup. Let me explain by Models

Models.py

class User(AbstractUser):
    is_employee = models.BooleanField(default=False)
    is_client = models.BooleanField(default=False)

class Client(models.Model):
   
    user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
    client_name = models.CharField(max_length=500, default=0)


class MaterialRequest(models.Model):

    owner = models.ForeignKey(User, on_delete=models.CASCADE)
    flows = models.ManyToManyField(MaterialRequestFlow)
    is_allocated = models.BooleanField(default=False)

class Allotment(models.Model):

    transaction_no = models.IntegerField(default=0)
    dispatch_date = models.DateTimeField(default=datetime.now)
    send_from_warehouse = models.ForeignKey(Warehouse, on_delete=models.CASCADE)
    sales_order = models.ForeignKey(MaterialRequest, on_delete=models.CASCADE)

Now I want to query Allotment which are created by a particular Client. In the frontend I have a dropdown of Clients which sends the id of the Client

Here's my function for this:

Views.py

class AllotmentReport(APIView):
    permission_classes = (permissions.IsAuthenticated,)

    def get(self, request, *args, **kwargs):
        cname = self.kwargs['cname']
        if self.kwargs['cname']:
            items = Allotment.objects.filter(sales_order__owner??? = cname).order_by('-id')    #Need Help Here
        else:
            items = Allotment.objects.all().order_by('-id')
            
        serializer = AReportSerializer(items, many=True)

        return Response(serializer.data, status=status.HTTP_201_CREATED)

Also I'd like to know If there is a better alternative to do that

2
  • What value you are providing by cname? Commented Jul 27, 2020 at 11:46
  • 'id' of 'Client` Model Commented Jul 27, 2020 at 11:47

2 Answers 2

1
def get(self, request, *args, **kwargs):
        cname = self.kwargs['cname']
        if self.kwargs['cname']:
            client = Client.objects.get(id=cname)
            items = Allotment.objects.filter(sales_order__owner=client.user).order_by('-id')
        else:
            items = Allotment.objects.all().order_by('-id')
            
        serializer = AReportSerializer(items, many=True)

    return Response(serializer.data, status=status.HTTP_201_CREATED)
Sign up to request clarification or add additional context in comments.

4 Comments

I am getting NameError: name 'client__user' is not defined
oh my bad. Updated the answer
One more help please ? I am getting the data in 5.13 s and size is 45.35 KB, basically 100 objects and that even without using depth. Can I speed it up ?
One solution is to take created_by field in Allotment, ForeignKey of user, and update after creating a record. Then no need for a nested filter.
0

You can get the user through the client and then get the MaterialRequest owners by filtering on those users.

material_request_owners = []

try:
    user = Client.objects.get(id=cname).user
    material_request_owners = MaterialRequest.objects.filter(owner=user)     
except (AttributeError, Client.DoesNotExist():
    return # error message


if len(material_request_owners) > 0:     
    items = Allotment.objects.filter(sales_order=material_request_owners).order_by('-id')
else:
    items = Allotment.objects.all().order_by('-id')

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.