如何使用 django rest 在嵌套的 Serializer 上调用实例方法?
How to call instance methods on the nested Serializer with django rest?
我有两个模型要嵌套在一起。 Timesheet
和 Invoice
我的 InvoiceSerializer
看起来像这样:
class InvoiceSerializer(serializers.ModelSerializer):
billable_timesheets = serializers.SerializerMethodField()
total_hours_and_cost = serializers.SerializerMethodField()
class Meta:
model = Invoice
fields = (
"hours",
"hour_cost",
"billable_timesheets",
"total_hours_and_cost",
...
)
def get_total_hours_and_cost(self, obj):
return obj.hours * obj.hour_cost
def get_billable_timesheets(self, obj):
"""Getting all timesheets for selected billable period"""
timesheets = obj.project.timesheets.filter(<queryset here>)
return TimesheetSerializer(timesheets, many=True).data
一切正常 - 我可以定义 MethodFields 并返回正确的 JSON,太棒了。但是,我在我的子模型(在本例中为 Timesheet
模型)上获得了一个方法,我需要访问该方法并运行 进行一些计算。我正在通过 get_billable_timesheets
获取必要的数据,现在我需要 运行 在我的 Timesheet model
上调用一个名为 total_duration()
的方法。每当我尝试按照
的方式做某事时
timesheets = self.get_billable_timesheets(obj)
hours = 0
for timesheet in timesheets:
hours += timesheet.total_duration()
我得到:
AttributeError: 'collections.OrderedDict' object has no attribute 'total_duration'
我不明白的是,我实际上已经通过 get_billable_timesheets
方法序列化了数据 - 为什么我仍然收到此错误?
for 循环中的时间表是一个有序的 dict 实例,因为 get_billable_timesheets returns 序列化数据。
解决方法是,
timesheets = self.get_billable_timesheets(obj)
hours = 0
for timesheet in timesheets:
timesheet_id = timesheet.get('id')
timesheet_obj = Timesheet.objects.get(id=timesheet_id)
hours += timesheet_obj.total_duration()
我的案例的一个可行解决方案是不 return 时间表的序列化版本,(例如,而不是 return TimesheetSerializer(timesheets, many=True).data
我刚刚做了 return timesheets
→ 做了我的计算需要然后序列化时间表:
def get_billable_timesheets(self, obj):
"""Getting all timesheets for selected billable period"""
timesheets = obj.project.timesheets.filter(<queryset here>)
return timesheets # instead of a serialized version
我有两个模型要嵌套在一起。 Timesheet
和 Invoice
我的 InvoiceSerializer
看起来像这样:
class InvoiceSerializer(serializers.ModelSerializer):
billable_timesheets = serializers.SerializerMethodField()
total_hours_and_cost = serializers.SerializerMethodField()
class Meta:
model = Invoice
fields = (
"hours",
"hour_cost",
"billable_timesheets",
"total_hours_and_cost",
...
)
def get_total_hours_and_cost(self, obj):
return obj.hours * obj.hour_cost
def get_billable_timesheets(self, obj):
"""Getting all timesheets for selected billable period"""
timesheets = obj.project.timesheets.filter(<queryset here>)
return TimesheetSerializer(timesheets, many=True).data
一切正常 - 我可以定义 MethodFields 并返回正确的 JSON,太棒了。但是,我在我的子模型(在本例中为 Timesheet
模型)上获得了一个方法,我需要访问该方法并运行 进行一些计算。我正在通过 get_billable_timesheets
获取必要的数据,现在我需要 运行 在我的 Timesheet model
上调用一个名为 total_duration()
的方法。每当我尝试按照
timesheets = self.get_billable_timesheets(obj)
hours = 0
for timesheet in timesheets:
hours += timesheet.total_duration()
我得到:
AttributeError: 'collections.OrderedDict' object has no attribute 'total_duration'
我不明白的是,我实际上已经通过 get_billable_timesheets
方法序列化了数据 - 为什么我仍然收到此错误?
for 循环中的时间表是一个有序的 dict 实例,因为 get_billable_timesheets returns 序列化数据。
解决方法是,
timesheets = self.get_billable_timesheets(obj)
hours = 0
for timesheet in timesheets:
timesheet_id = timesheet.get('id')
timesheet_obj = Timesheet.objects.get(id=timesheet_id)
hours += timesheet_obj.total_duration()
我的案例的一个可行解决方案是不 return 时间表的序列化版本,(例如,而不是 return TimesheetSerializer(timesheets, many=True).data
我刚刚做了 return timesheets
→ 做了我的计算需要然后序列化时间表:
def get_billable_timesheets(self, obj):
"""Getting all timesheets for selected billable period"""
timesheets = obj.project.timesheets.filter(<queryset here>)
return timesheets # instead of a serialized version