我已经更新了我的代码——我想在 "for loop" 中传递一个带有 employee_id 的对象和他的具体捐赠金额,我该怎么做?

I have updated my code-- I want to pass an object in "for loop" with employee_id and his specific donation amount, How can I do this?

我正在开发一个捐赠应用程序。在此应用程序中,有一项功能可以向组织的每位员工发送等量的捐款,现在他们想通过向所有或部分员工发送自定义金额的捐款来更改此功能。 我已经研究过了:现在我正在使用一个 for 循环,它遍历员工 ID 列表并为每个 ID 提供金额。但我想要的是在 for loop 中传递一个对象,其中该对象具有来自 list of idsid 和来自 payloadamount。我想将 id 与他特定的 amount 锁定在一个对象中 这是我的代码:

class BusinessDonationController(BaseController):
    def create(self, request, response, business):
        employees =Employment.objects.filter(business=business, active=True)
        ids = employees.values_list('id', flat=True)
        donation_amount = []
        for id in ids:
            try:
                amount = int(request.payload.get("amount"))
                donation_amount.append({
                    "id" : id,
                    "amount" : amount
                })
            except ValueError:
                return response.bad_request("Invalid donation amounts, %s, should be in whole dollars" % amount)
        return donation_amount

我能想到的一个办法是,你可以自定义some/all名员工的捐款数额,剩下的平均分给其他人。例如:

I want to donate ,000 to 10 employees. Originally, each of them would receive 00. But I want Employee-A and Employee-B to receive 00 and 00 respectively. Now I am left with 00 and 8 employees. So, each 8 of them will receive 62.5.

实施:(AJAX + DRF)

您必须在 front-end 中添加一些输入字段。这是为了自定义哪个员工应该接受多少捐赠。您应该跟踪 employeeId,因为稍后在将负载发送到您的服务器时需要它。

像这样创建一个 JSON 列表(从您的表单)并将其传递给 API 调用。

let payload = [
    {"employee_id": 1, "amount": 1300.0},
    {"employee_id": 2, "amount": 1200.0},
]

您可以使用任何方法发送数据。例如:在 AJAX 你会这样:

$.ajax({
    type: "POST",
    url: "/your/api/endpoint/",
    data: {
        // Send `donation_amount` too.
        // This will help to validate data in backend.
        donation_amount: 10000.0,

        customized_amounts: payload
    },
    traditional: true,

    beforeSend: function () {
        // show some loading animation.
    },

    success: function (data) {
        // show a success toast or redirect.
    },

    error: function (error) {
        // show some error toast.
    },
});

在后端创建一个序列化器:

from rest_framework import serializers
from django.utils.text import gettext_lazy as _

# TODO: from .models import Business


class DonationSerializer(serializers.Serializer):
    business = serializers.PrimaryKeyRelatedField(label=_('Business'), queryset=Business.objects.all(), required=True)
    donation_amount = serializers.FloatField(label=_('Donation Amount'), required=True, min_value=0.0)
    customized_amounts = serializers.JSONField(label=_('Customized Amounts'), default=list, required=False)

    def validate(self, attrs):
        donation_amount = attrs.get('donation_amount', 0.0)
        customized_amounts = attrs.get('customized_amounts', [])

        if donation_amount == 0.0:
            raise serializers.ValidationError(_('Donation cannot be empty!'))

        partial_sum = 0.0
        for data in customized_amounts:
            # Checking if employee_id is valid or not
            employee_id = data.get('employee_id')
            if not Employment.objects.filte(id=employee_id).exitst():
                raise serializers.ValidationError(_(f'Employee with id: ${employee_id} does not exists!'))

            # summing up amount to check if it exceeds total amount
            partial_sum += data.get('amount')

        if partial_sum > donation_amount:
            raise serializers.ValidationError(_('Individual donation amount exceeds total amount!'))

        # add any other validation you want.

        return attrs

    def update(self, instance, validated_data):
        pass

    def create(self, validated_data):
        pass

和一个API端点:

from rest_framework import status
from rest_framework.generics import GenericAPIView
from rest_framework.response import Response

# TODO: from .models import Employment
# TODO: from .tasks import run_employee_donation


class DonationCreateAPIView(GenericAPIView):
    def post(self, request, *args, **kwargs):
        serializer = DonationSerializer(data=request.data, context={'request': request})
        serializer.is_valid(raise_exception=True)

        business = serializer.validated_data.get('business')
        donation_amount = serializer.validated_data.get('donation_amount')
        customized_amounts = serializer.validated_data.get('customized_amounts')

        employee_qs = Employment.objects.filter(business=business, active=True)
        total_employees = employee_qs.count()

        donation_per_employee = donation_amount / (total_employees - len(customized_amounts))

        for employee in employee_qs:
            customized_amount = [data for data in customized_amounts if data['employee_id'] == employee.id]

            if len(customized_amount) > 0:
                # Customized donation for this employee found.
                run_employee_donation(employee_id=employee.id, amount=customized_amount[0].get('amount'))
            else:
                run_employee_donation(employee_id=employee.id, amount=donation_per_employee)

        return Response({'success': True}, status=status.HTTP_201_CREATED)

创建一个模型来存储员工和捐赠。列出所有员工。用户可以单击员工姓名以显示用于编辑金额的表单。

这对我有用!!

class BusinessDonationController(BaseController):
    def create(self, request, response, business):
        business = Business.objects.get(id=business)
        employees =Employment.objects.filter(business=business, active=True)
        ids = employees.values_list('id', flat=True)
        donation_amount = []
        try:
            employee_id = int(request.payload.get("employee_id"))
            amount = int(request.payload.get("amount"))
            donation_amount.append({
                "employee_id" : employee_id,
                "amount" : amount
            })
        except ValueError:
            return response.bad_request("Invalid donation amounts, %s, should be in whole dollars" % amount)

        for employee in employees:
            if employee.id == employee_id:
                credit_account = CreditAccount.objects.create(deposit=deposit, total_amount=amount, current_amount=amount, employment=employee)
        if error != '' and error is not None:
            return response.bad_request(error)

        response.set(**{'success': True})