Reputation: 9796
I'm using Django 2.0
and Django REST Framework
.
I have two models contact
and transaction
as below
contact model
class Contact(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100, blank=True, null=True)
amount given model
class AmountGiven(models.Model):
contact = models.ForeignKey(Contact, on_delete=models.PROTECT)
amount = models.FloatField(help_text='Amount given to the contact')
interest_rate = models.FloatField(blank=True, default=None, null=True, help_text='% of interest to be calculated')
_given_date = models.DateTimeField(
db_column='given_date',
default=timezone.now,
help_text='Date and time when amount was given to the contact'
)
def __str__(self):
return str(self.amount)
@property
def given_date(self):
return self._given_date
@given_date.setter
def given_date(self, value):
self._given_date = value
@property
def interest_to_pay(self):
if self.interest_rate:
datetime_diff = datetime.now(get_localzone()) - self.given_date
days = datetime_diff.days
duration_in_year = days/365
simple_interest_amount = (self.amount * duration_in_year * self.interest_rate)/100
return simple_interest_amount
return 0
@property
def total_payable(self):
return self.amount + self.interest_to_pay
@property
def amount_due(self):
returned_amount = 0
for returned in self.amountreturned_set.all():
returned_amount += returned.amount
return self.total_payable - returned_amount
and ContactSerializer
class ContactSerializer(serializers.HyperlinkedModelSerializer):
url = serializers.HyperlinkedRelatedField(
view_name='contacts:detail',
read_only=True
)
user = serializers.CurrentUserDefault()
amount_due = ReadOnlyField(source='amountgiven__amount_due')
class Meta:
model = Contact
fields = ('url', 'id', 'first_name', 'last_name', 'full_name', 'amount_due')
and in views.py
class ContactViewSet(viewsets.ModelViewSet):
serializer_class = ContactSerializer
permission_classes = (IsAuthenticated, AdminAuthenticationPermission,)
def get_queryset(self):
return Contact.objects.filter(user=self.request.user)
def perform_create(self, serializer):
serializer.save(user=self.request.user)
But there is no field as amount_due
and url
in the response returned while making the request to /contacts/
endpoint with GET
method.
Upvotes: 0
Views: 3001
Reputation: 2040
Based on your comment, you want the sum of all the amounts(please edit your question). so you should use annotate in your queryset:
from django.db.models import Sum
def get_queryset(self):
return Contact.objects.filter(user=self.request.user).annotate(amount_due=Sum('amountgiven_set__amount'))
(I recommend using modelManager for the queryset and the filtering instead of doing it here)
and add a field like this to your serializer:
amount_due = serializer.IntegerFiled()
Upvotes: 2
Reputation: 3091
Your modeling doesn't allow you to access amount_due in the way which you'd like.
Your Contact
model does not have amountgiven
attribute.
It does however have amountgiven_set
which you can use to obtain a queryset of amountgiven for given contact.
But there can be multiple ones so you need to decide which amount_due
you want to display in your serializer.
You can use SerializerMethodField
to serializer the value of amount_due which you would like:
class ContactSerializer(serializers.HyperlinkedModelSerializer):
amount_due = serializers.SerializerMethodField()
def get_amount_due(self, obj):
amountgiven = obj.amountgiven_set.first()
return amountgiven.amount_due
But again, as i already mentioned - amountgiven_set returns a queryset where you can have multiple objects.
In case you are sure you have only one for given contact, you can use first()
as in my example to get it.
Upvotes: 0