Добавление данных на основе запроса в ответ API (Django REST Framework)

Я создаю API для приложения калькулятора платежей по кредиту с помощью Python, Django и Django REST framework.

Для того, чтобы расчет работал, необходимо получить доступ к данным о сроке кредита и сумме кредита, которые пользователь предоставляет в своем запросе, и использовать их вместе с данными из базы данных. Я застрял на том, как этого добиться. Я хотел бы иметь ключ 'payment' в JSON ответе, значение которого равно вычисленной сумме. Буду очень признателен за любой совет по этому поводу.

Вот функция, которую я придумал, которая рассчитывает ежемесячный платеж, принимая в качестве аргументов оба данных из базы данных ('term_min', 'term_max', 'rate_min', 'rate_max', 'payment_min', 'payment_max') а также параметры запроса (term и price), но я не могу понять, как включить это в мое представление, чтобы мой ответ API содержал результирующее значение:

def calculate_payment(term_min, term_max, rate_min, rate_max, term, loan):
    
    if term == term_min:
        int_rate = rate_min
    elif term == term_max:
        int_rate = rate_max
    else:
        term_proportion = (term - term_min)/(term_max - term_min)
        int_rate = (rate_max / 100 - rate_min/100) * term_proportion

    term_in_months = 12 * term
    monthly_pmt = loan * ((1 + int_rate) ** term_in_months) / ((1 + int_rate) ** term_in_months - 1)
    return monthly_pmt

Я пробовал ModelSerializerField, но он, похоже, использует только поля базы данных, и, похоже, нет способа передать параметры запроса, необходимые для вычисления.

Вот моя модель, сериализатор и представление:

models.py:

class Offer(models.Model):
    
    term_min = models.PositiveSmallIntegerField()
    term_max = models.PositiveSmallIntegerField()
    rate_min = models.FloatField()
    rate_max = models.FloatField()
    payment_min = models.PositiveIntegerField()
    payment_max = models.PositiveIntegerField()

serializers.py:

class OfferSerializer(serializers.ModelSerializer):

    class Meta:
        model = Offer
        fields = ['term_min', 'term_max', 'rate_min', 'rate_max', 'payment_min', 'payment_max']

views.py:

class OfferViewSet(viewsets.ModelViewSet):
    queryset = Offer.objects.all()
    serializer_class = OfferSerializer

    def get_queryset(self, *args,**kwargs):
        queryset = super().get_queryset(*args, **kwargs)
        loan = self.request.GET.get('price', None)
        term = self.request.GET.get('term', None)
        if price and deposit and term:
            loan_amount = int(price) - int(price) * (int(deposit) / 100)
            queryset = queryset.filter(term_min__lte=term, term_max__gte=term, payment_min__lte=loan_amount, payment_max__gte=loan_amount)
            return queryset
        else:
            return Offer.objects.all()

Чтобы добавить данные из параметров запроса, мне потребовалось:

  1. добавить контекст из представления в сериализатор (очень помог следующий результат поиска: https://ilovedjango.com/django/rest-api-framework/views/tips/context-in-django-rest-framework/). Это потребовало переопределения методов get_serializer_context и create в моем ModelViewSet. Изменения, которые я внес в файл views.py в своем посте, были следующими:
def get_serializer_context(self):
        context = super(OfferViewSet, self).get_serializer_context()
        context.update({"deposit": self.request.GET.get("deposit", None)})
        context.update({"price": self.request.GET.get("price", None)})
        context.update({"term": self.request.GET.get("term", None)})
        return context
  1. используйте SerializerMethodField (см. документацию DRF: https://www.django-rest-framework.org/api-guide/fields/#serializermethodfield) для добавления вычисляемого поля в сериализатор.
Вернуться на верх