Добавление данных на основе запроса в ответ 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()
Чтобы добавить данные из параметров запроса, мне потребовалось:
- добавить контекст из представления в сериализатор (очень помог следующий результат поиска: 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
- используйте
SerializerMethodField
(см. документацию DRF: https://www.django-rest-framework.org/api-guide/fields/#serializermethodfield) для добавления вычисляемого поля в сериализатор.