Как я могу обновить поле модели из другой модели в django? - PullRequest
0 голосов
/ 26 апреля 2020

my models.py:

class clients(models.Model):
    client_id = models.IntegerField(unique=True, primary_key=True )
    '
    '
    money = models.IntegerField(default = 0)


class transfermoney(models.Model):
    first_client_id = models.IntegerField()
    second_client_id = models.IntegerField()
    amountofmoney = models.PositiveIntegerField()
    time = models.TimeField(auto_now=True)
    date = models.DateField(auto_now=True)

my serializers.py:

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = clients
        fields = ('__all__')

 class moneytransfer(serializers.ModelSerializer):
 class Meta:
        model = transfermoney
        fields = ('__all__')

my views.py:

class transferingmoney(APIView):
        def post(self,request):
            serializer = moneytransfer(data=request.data)
            if serializer.is_valid():
                serializer.save()
                return Response(serializer.data, status=status.HTTP_201_CREATED)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

i ' Я использую django rest framework, и я хочу, чтобы каждый раз, когда я делаю запрос на публикацию в модель «TransferMoney», он берет «first_client_id» и ищет его в «client_id» в модели «клиентов» и добавляет "сумма денег" из модели "перевод денег" в поле "деньги" в модели "клиенты", и то же самое для "second_client_id"

пожалуйста, как я могу это сделать?

1 Ответ

0 голосов
/ 26 апреля 2020

Хорошо, вопрос о том, как сделать это полностью правильно, слишком велик, чтобы обсуждать это здесь. Я отвечу только на ваш вопрос.

Но вещь, которую я должен упомянуть - хранить денежные суммы в десятичных полях, а не в Integer - это просто плохая практика. Что-то вроде:

models.DecimalField(max_digits=6, decimal_places=2)

подойдет. Теперь к предмету вопроса.

Прежде всего, я предлагаю вам добавить собственный метод validate () в ваш сериализатор денежного перевода и добавить туда проверки client_ids. Вы используете целочисленные поля (по некоторым причинам, я думаю) в своей модели TransferMoney вместо Foreign Keys. Из-за этого метод validate serializeек не будет проверять, существуют ли эти идентификаторы, поэтому лучше добавить некоторую проверку. Затем он будет вызван в вашем View и вернет False, если ваши пользовательские проверки не пройдут. Если я правильно понял, вы хотите что-то вроде:

class BillingRecordSerializer(serializers.ModelSerializer):
    def validate(self, data):
        try:
            clients.objects.get(client_id = data['first_client_id'])
            clients.objects.get(client_id = data['second_client_id'])
        except clients.DoesNotExist:
            raise serializers.ValidationError("One of the clients does not exist")
    return data

    class Meta:
        fields = ('__all__')
        model = transfermoney

С этим вы будете уверены, что оба клиента присутствуют в вашей БД. Затем вы можете сделать что-то вроде:

class transferingmoney(APIView):
        def post(self,request):
            data=request.data
            serializer = moneytransfer(data=data)
            if serializer.is_valid():
                serializer.save()
                client_1 = clients.objects.get(client_id=data['first_client_id'])
                client_2 = clients.objects.get(client_id=data['second_client_id'])
                client_1.money -= data['amountofmoney']
                client_2.money += data['amountofmoney']
                client_1.save()
                client_2.save()
                return Response(serializer.data, status=status.HTTP_201_CREATED)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

Вы также можете создать отдельный метод для логики c, который я добавил в представление, чтобы сделать код понятным и пригодным для повторного использования. Лично я предпочел бы переопределить метод save () модели TransferMoney, чтобы сделать это там. И тогда он будет автоматически вызван при первом сохранении () этой модели. Но все зависит от того, в каком месте вам будет удобнее и какова логика c за вашим кодом.

И я хочу отметить, что это, очевидно, не правильный способ иметь дело с денежными транзакциями, но правильное описание - это путь к топике c вопроса, а также есть множество примеров.

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

...