ListCreateAPIView POST с аннотированным полем в сериализаторе, а не в модели - PullRequest
0 голосов
/ 05 ноября 2018

Я создаю простое приложение для составления бюджета для изучения Django & React. Я использовал DRF для создания API для создания и получения транзакций из базы данных. В настоящее время я вычисляю общий баланс на ходу, когда делаю свой GET. Это работает хорошо, но когда я делаю POST, я получаю ошибку, что мое поле динамического баланса является обязательным, так как это поле находится в моем сериализаторе. Как я могу обойти это?

views.py

class CreateView(generics.ListCreateAPIView):
    """This class defines the GET & POST behavior of the rest api."""

    queryset = Transaction.objects.all()

    # This is the balance that's calculated on the fly
    queryset_with_balance = queryset.annotate(balance=Window(Sum('amount'),
                                                             order_by=F('created_time').asc())).all().order_by('-created_time')

    serializer_class = TransactionSerializer

    def perform_create(self, serializer):
        """Save the post data when creating a new transaction."""
        serializer.save()

    def get_queryset(self):
        return self.queryset_with_balance

serializers.py

class TransactionSerializer(serializers.ModelSerializer):
    balance = serializers.DecimalField(decimal_places=2, max_digits=19)

    class Meta:
        """Meta class to map serializer's fields with the model fields."""
        model = Transaction
        fields = ('id', 'date', 'payee', 'category',
                  'amount', 'balance', 'created_time', 'modified_time')

models.py

class Transaction(models.Model):
    date = models.DateField()
    payee = models.CharField(max_length=256)
    category = models.CharField(max_length=256)
    amount = MoneyField(max_digits=19,
                        decimal_places=2,
                        default_currency='USD')    
    created_time = models.DateTimeField(auto_now_add=True)
    modified_time = models.DateTimeField(auto_now=True)

1 Ответ

0 голосов
/ 05 ноября 2018

установить balance поле как read_only, как показано ниже,

class TransactionSerializer(serializers.ModelSerializer):
    balance = serializers.DecimalField(decimal_places=2, max_digits=19, <b>read_only=True</b>)
    # your code



Из документа DRF

Поля только для чтения включены в выходные данные API, , но не должны включаться во входные данные во время операций создания или обновления .

...