Reputation: 656
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
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