2015-07-28 4 views
1

Итак, у меня есть модель, у которой есть атрибут, который будет автоматически рассчитан, когда api получит запрос POST. Модель представляет собой модель счета, в которой суммарный платеж рассчитывается на numberOfHours * paymentRate. Django не позволяет мне это сделать, установив значение по умолчанию. Есть ли способ сделать это?Автоматический расчет по полю в модели в Django RESTframework

Модель

class Bill(models.Model): 
    billID = models.AutoField(primary_key=True) 
    bill_dt = models.DateField() 
    hours = models.FloatField() 
    workAssignmentID_fk = models.ForeignKey(WorkAssignment, null=True, default=None) 
    totalPayment = models.FloatField(default=0) 

    def __unicode__(self): 
     return u'%s' % (self.bill_dt) 

    def __str__(self): 
     return u'%s' % (self.bill_dt) 

Serializer

class ReadBillSerializer(serializers.HyperlinkedModelSerializer): 
    workAssignmentID_fk = ReadWorkAssignmentSerializer() 

    class Meta: 
     model = Bill 
     fields = ('url', 'bill_dt', 'hours', 'workAssignmentID_fk', 'totalPayment') 

class WriteBillSerializer(serializers.HyperlinkedModelSerializer): 
    class Meta: 
     model = Bill 
     fields = ('url', 'bill_dt', 'hours', 'workAssignmentID_fk', 'totalPayment') 

Посмотреть

class BillViewSet(viewsets.ModelViewSet): 
    queryset = Bill.objects.all() 

    def get_serializer_class(self, *args, **kwargs):   
     if self.request.method == 'POST' or self.request.method == 'PUT': 
      return WriteBillSerializer 
     return ReadBillSerializer 

В модели Билл, я хочу totalPayment = часы * workAssignmentID_fk.paymentRate.

paymentRate - это атрибут в workAssignmentID_fk.

+0

Пожалуйста, добавьте код для сериализаторов, моделей и видов. Поле «numberofhours» и «paymentRate» модели? Вы используете модельный сериализатор? –

+0

Спасибо, @RahulGupta за быстрый ответ. Я отредактировал вопрос. Пожалуйста, посмотрите –

+0

Как мы получим объект 'workAssignmentID_fk' в случае запроса POST –

ответ

1

Вы можете переопределить функцию perform_create() на ваш взгляд и передать значение totalPayment методу серийного ввода save().

perform_create() вызывается при сохранении экземпляра нового объекта. Вы можете использовать этот крюк создания объекта.

class BillViewSet(viewsets.ModelViewSet): 
    queryset = Bill.objects.all() 

    def get_serializer_class(self, *args, **kwargs):   
     if self.request.method == 'POST' or self.request.method == 'PUT': 
      return WriteBillSerializer 
     return ReadBillSerializer 

    def perform_create(self, serializer): 
     hours = serializer.validated_data['hours'] # get the value of hours 
     work_assignment_object = <get_the_workAssignmentID_fk_object_from_passed_url> 
     payment_rate = work_assignment_object.paymentRate # get the value of 'paymentRate' from work assignment object 
     total_payment = hours*payment_rate # calculate value of total payment 
     serializer.save(total_payment=total_payment, workAssignmentID_fk=work_assignment_object) # pass the value of total payment to be saved and the work assignment object 
+0

Итак, если у меня есть другие атрибуты в модели счета, нужно ли передавать их также в методе serializer.save? –

+0

Вы должны передать только те атрибуты, которые вы не являетесь 'POSTING', чтобы объект сохранялся со всеми необходимыми атрибутами. Я предположил, что вы не передаете только 2 поля 'workAssignmentID_fk' object и' totalPayment' в почтовых данных, все остальные поля, которые вы передаете. Поэтому, когда объект сохраняется, он получит эти 2 поля из '.save()' kwargs и других полей из 'serializer.validated_data'. –

+0

Спасибо @RahulGupta много, это сработало. –

Смежные вопросы