Django REST Framework:响应中缺少序列化程序字段
我正在使用Django REST Framework:响应中缺少序列化程序字段,django,django-rest-framework,Django,Django Rest Framework,我正在使用Django 2.0和Django REST框架 我有两种型号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=
Django 2.0
和Django REST框架
我有两种型号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
给定型号的金额
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')
并在视图中.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)
但是在使用
GET
方法向/contacts/
端点发出请求时返回的响应中没有amount\u due
和url
字段。您的建模不允许您以想要的方式访问amount\u due
您的联系人
型号没有amountgiven
属性。
但是,它确实有amountgived\u集
,您可以使用该集获取给定联系人的amountgived查询集
但是可以有多个,因此您需要决定要在序列化程序中显示哪个到期金额
您可以使用SerializerMethodField
序列化您想要的到期金额的值:
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()
来获取它。您的建模不允许您以您希望的方式访问到期金额
您的联系人
型号没有amountgiven
属性。
但是,它确实有amountgived\u集
,您可以使用该集获取给定联系人的amountgived查询集
但是可以有多个,因此您需要决定要在序列化程序中显示哪个到期金额
您可以使用SerializerMethodField
序列化您想要的到期金额的值:
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()
来获取它。根据您的评论,您需要所有金额的总和(请编辑您的问题)。因此,您应该在查询集中使用注释:
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()
根据您的评论,您需要所有金额的总和(请编辑您的问题)。因此,您应该在查询集中使用注释:
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()
实际上,没有
到期金额
列,是的,对于单个联系人
,给定的金额
可以有多条记录。我只是把给联系人的所有金额加起来,以返回到期金额。那么,我应该使用ModelManager
方法而不是model方法吗?您可以在序列化程序中对其进行总结。在我的示例中,您可以使用serializerMethodField并在该方法中执行它。但我喜欢这个问题的另一个答案中的方法。因此,请看这一个。使用ModelManager
返回模型中所有amount\u due
的总和,因为用户可能有许多记录,并且模型类中的amount\u due
正在基于实体计算特定实体的到期金额。实际上没有amount\u due
列,是的对于一个联系人
给定的金额
可以有多个记录。我只是把给联系人的所有金额加起来,以返回到期金额。那么,我应该使用ModelManager
方法而不是model方法吗?您可以在序列化程序中对其进行总结。在我的示例中,您可以使用serializerMethodField并在该方法中执行它。但我喜欢这个问题的另一个答案中的方法。因此,请看这一个。使用ModelManager
返回模型中所有amount\u due
的总和,因为用户可能有许多记录,并且模型类中的amount\u due
正在基于实体计算特定实体的到期金额。