Anjaan
Anjaan

Reputation: 656

How can I show specific users data into the serializer through django?

I am trying to create a portfolio of users for the stock market. I have custom users model like this:

class CustomUsers(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(unique=True, db_index=True,null=True)
    phone_no = models.CharField(max_length=50,null=True,unique=True)
    first_name = models.CharField(max_length=120, blank=True)
    last_name = models.CharField(max_length=120, blank=True)
   
    is_admin = models.BooleanField('admin', default=False)
    
    is_active = models.BooleanField(
        _('active'),
        default=True,
        help_text=_(
            'Designates whether this user should be treated as active. '
            'Unselect this instead of deleting accounts.'
        ),
    )
    is_staff = models.BooleanField(
        _('staff status'),
        default=False,
        help_text=_(
            'Designates whether the user can log into this admin site.'
        ),
    )
    date_joined = models.DateTimeField(
        _('date joined'), default=timezone.now
    )
    objects = CustomUserManager()

    def get_full_name(self):
        return (self.first_name +" " +self.last_name)

I have another app called portfolio and I have two models in it. They are like this:

class MyShares(models.Model):

    TYPE = (
        ('IPO',_('IPO')),
        ('FPO', _('FPO')),
        ('Secondary',_('Secondary')),
        ('Bonus', _('Bonus')),
        ('Rights', _('Rights')),
        ('Auction', _('Auction'))

    )
    SHARE_STATUS = (
        ('Owned',_('Owned')),
        ('Sold',_('Sold'))
    )
    user = models.ForeignKey("users.CustomUser", verbose_name=_("User"), on_delete=models.CASCADE, related_name='my_shares')
    stock_symbol = models.ForeignKey("finance.Organization", verbose_name=_("Stock Symbol"), on_delete=models.CASCADE)
    buy_date = models.DateField(_("Buy Date"), auto_now=False, auto_now_add=False)
    sell_date = models.DateField(_("Sell Date"), auto_now=False, auto_now_add=False, null=True, blank=True)
    buy_price = models.FloatField(_("Buy Price"))
    sell_price = models.FloatField(_("Sell Price"),null=True,blank=True)
    quantity = models.PositiveIntegerField(_("Quantity"))
    share_type = models.CharField(_("Type"), choices=TYPE, default='IPO', max_length=50)
    share_status = models.CharField(_("Status"),choices=SHARE_STATUS,default='Owned', max_length=50)

    
    def __str__(self):
        # if self.user.first_name:
        #     return self.user.get_full_name()
        return self.stock_symbol.symbol
    
class Portfolio(models.Model):
    user = models.ForeignKey("users.CustomUser", verbose_name=_("User"), on_delete=models.CASCADE, related_name='portfolio')
    my_shares = models.ManyToManyField("portfolio.MyShares", verbose_name=_("Shares"))

    def __str__(self):
        if self.user.first_name:
            return self.user.get_full_name()
        return self.user.email

Here, Organization is another model in another app that tracks the current organizations listed in the share market. My serializer for the Portfolio is as follows:


class MySharesSerializer(serializers.ModelSerializer):
    user = serializers.ReadOnlyField(source='user.get_full_name')
    class Meta:
        model = MyShares
        fields = (
            'user',
            'stock_symbol',
            'buy_date',
            'buy_price',
            'quantity',
            'sell_date',
            'sell_price',
            'share_type',
            'share_status'
        )

class PortfolioSerializer(serializers.ModelSerializer):
    my_shares = MySharesSerializer(many=True).data
    user = serializers.ReadOnlyField(source='user.get_full_name')
    class Meta:
        model = Portfolio
        fields = (
            'user',
            'my_shares'
        )

I want the output to be like this:

"results": [
    {
      "user": "USER1",
      "my_shares": [
      {
      "user": "USER1",
      "stock_symbol": 801,
      "buy_date": "2021-03-10",
      "buy_price": 510,
      "quantity": 200,
      "sell_date": null,
      "sell_price": null,
      "share_type": "IPO",
      "share_status": "Owned"
      }
    ]
    }
  ]

Instead, it shows the output to be:

"results": [
    {
      "user": "USER1",
      "my_shares": []
    }
  ]

So, my question is how can I achieve my desired output, and Is there any way to filter the MySharesSerializer data with the specific user of the portfolio?

Upvotes: 1

Views: 144

Answers (1)

gardi
gardi

Reputation: 111

You can override the to_representation method in your serializer

class PortfolioSerializer(serializers.ModelSerializer):
    
    user = serializers.ReadOnlyField(source='user.get_full_name')
    class Meta:
        model = Portfolio
        fields = (
            'user'
        )
    
    def to_representation(self, instance):
        data = super().to_representation(instance)
        data["my_shares"] = MySharesSerializer(instance.my_shares.all(), many=True).data
        return data

Upvotes: 1

Related Questions