Django rest framework - "Это поле обязательно для заполнения".

У меня есть два класса, класс Amount и Transaction

class Account(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
account_number = models.BigIntegerField(unique=True)
currency = models.CharField(max_length=3)
balance = models.DecimalField(max_digits=20, decimal_places=2, default=0)


class Transaction(models.Model):
sender_account_number = models.BigIntegerField()
recipient_account_number = models.BigIntegerField()
amount = models.DecimalField(max_digits=20, decimal_places=2)
date_creation = models.DateTimeField(auto_now_add=True)
account = models.ForeignKey(Account, on_delete=models.CASCADE)

Мои сериализаторы:

class TransactionSerializer(serializers.ModelSerializer):
    class Meta:
        model = Transaction
        fields = ['sender_account_number', 'recipient_account_number', 'amount', 'date_creation', 'account']
        extra_kwargs = {
            'date_creation': {'read_only': True},

        }``

class AccountSerializer(serializers.ModelSerializer):
    class Meta:
        model = Account
        fields = ['id', 'account_number', 'currency', 'balance', 'user']
        extra_kwargs = {
            'balance': {'read_only': True},
            'user': {'read_only': True},
        }

Я хочу добавить транзакцию в базу данных, но так, чтобы она автоматически устанавливала мой account_id на основе номера счета. Я попробовал метод perform_create

def perform_create(self, serializer):
    serializer.save(account=Account.objects.values('id').filter(
        account_number=self.request.data['sender_account_number']))

но я потерпел неудачу. Я получаю ошибку

{
"account": [
    "This field is required."
]

}

например, я хочу отправить эти данные

{

"sender_account_number": 346,
"recipient_account_number": 546,
"amount": 60

}

и метод Post:

def post(self, request):   
    serializer = TransactionSerializer(data=request.data)
    serializer.is_valid(raise_exception=True):
    return Response(serializer.data)
 

Как ее решить?

вы должны сообщить своему сериализатору транзакций, что счет является внешним ключом. И, следовательно, он будет ожидать объект вместо строки. add account = serializers.StringRelatedField(), как это

class TransactionSerializer(serializers.ModelSerializer):
        account = serializers.StringRelatedField()
        class Meta:
            model = Transaction
            fields = ['sender_account_number', 'recipient_account_number', 'amount', 'date_creation', 'account']
            extra_kwargs = {
                'date_creation': {'read_only': True},
    
            }``

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

def post(self, request):
    account_number = request.data.get('sender_account_number')
    account = Account.objects.get(account_number=account)
    serializer = TransactionSerializer(data=request.data)
    serializer.is_valid(raise_exception=True):
        serializer.save(account = account_number)
    return Response(serializer.data)
Вернуться на верх