1

I have basically three models.

class Users(models.Model):
    name = models.CharField(max_length=100)
    ...
class Portfolio(models.Model):
    name = models.CharField(max_length=50)
    user = models.ForeignKey(Users, on_delete=models.CASCADE, related_name='portfolio')
class BuySell(models.Model):
    portfolio = models.ForeignKey(Portfolio, on_delete=models.CASCADE, related_name='buy_sell'
    ...

Any user can have multiple portfolios and portfolios can have many buy-sell. From my viewset how can I access the portfolio instance selected by the user to add buy-sell data?

In my Viewset:

class BuySellViewSet(
        viewsets.GenericViewset, 
        mixins.ListModelMixin,
        mixins.CreateModelMixin,
        mixins.UpdateModelMixin,
        mixins.DestroyModelMixin
    ):
    
    serializer_class = BuySellSerializer
    queryset = BuySell.objects.all()
 
    def get_queryset(self):
        return self.request.user.portfolio

But when I add multiple portfolios for a single user I get the following error message:

TypeError at /api/v1/share/buy-sell/
Field 'id' expected a number but got <django.db.models.fields.related_descriptors.create_reverse_many_to_one_manager.<locals>.RelatedManager object at 0x7f857c7c6940>.

How can I select the correct portfolio instance to add buy-sell data inside that instance? Also, How'd I be adding new buy-sell records in an instance of a portfolio from my viewset?

def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        share = serializer.validated_data["share"]
        self.perform_create(serializer)
        return Response({"data": serializer.data}, status=status.HTTP_201_CREATED)
Sunderam Dubey
  • 1
  • 11
  • 20
  • 40
Anjaan
  • 595
  • 5
  • 19

1 Answers1

2

You can filter with:

class BuySellViewSet(
        viewsets.GenericViewset, 
        mixins.ListModelMixin,
        mixins.CreateModelMixin,
        mixins.UpdateModelMixin,
        mixins.DestroyModelMixin
    ):
    
    serializer_class = BuySellSerializer
 
    def get_queryset(self):
        return BuySell.objects.filter(portfolio__user=self.request.user)
Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
  • Filtering will give me the list of buy-sell items but if I have to create items inside one instance of one of the portfolios how'd I do that? – Anjaan Jul 14 '22 at 17:54
  • @Anjaan: how does the URL specifies the primary key of the portfolio? – Willem Van Onsem Jul 14 '22 at 17:55
  • I'm not sending pk in the URL, I'm using DRF and kinda stuck on how to choose an instance from the frontend. Using the CreateModelMixin for creating new buy-sell records but don't know how to choose the correct instance. – Anjaan Jul 14 '22 at 17:58
  • @Anjaan: well since a user can have multiple `Portfolio`s, you will need to send some unique key to identify the portfolio. Likely you should thus add the "create" logic in another view than the one where you list the buy/sell options. – Willem Van Onsem Jul 14 '22 at 18:02