我正在使用Django 2.0
和Django REST Framework
。
我有以下两个模型contact
和transaction
联系方式
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)
给定型号的数量
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
和 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')
和 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)
但是在使用amount_due
方法向url
端点发出请求时,返回的响应中没有/contacts/
和GET
字段。
答案 0 :(得分:2)
根据您的评论,您需要所有金额的总和(请编辑您的问题)。因此您应该在查询集中使用注释:
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'))
(我建议对查询集和过滤使用modelManager,而不是在此处进行操作)
并将这样的字段添加到序列化器中:
amount_due = serializer.IntegerFiled()
答案 1 :(得分:0)
您的建模方式不允许您以所需的方式访问amount_due。
您的Contact
模型没有amountgiven
属性。
但是,它确实具有amountgiven_set
,可用于获取给定联系人的数量查询集。
但是可以有多个,因此您需要确定要在序列化程序中显示哪个amount_due
。
您可以使用SerializerMethodField
来序列化您想要的amount_due的值:
class ContactSerializer(serializers.HyperlinkedModelSerializer):
amount_due = serializers.SerializerMethodField()
def get_amount_due(self, obj):
amountgiven = obj.amountgiven_set.first()
return amountgiven.amount_due
但是再次,正如我已经提到的-amountgiven_set返回一个查询集,您可以在其中拥有多个对象。
如果确定给定联系人只有一个,则可以像我的示例中那样使用first()
来获取它。