找出尝试发布数据时为什么收到HTTP 400错误代码的原因

时间:2019-01-18 21:04:33

标签: python django reactjs django-rest-framework

我正在尝试通过DRF API将其作为POST请求发送来创建订单,但始终收到“ ” POST / shop / orders / HTTP / 1.1“ 400 81 ”错误。 该错误显示“ {” total_price“:[”必填字段。“],” puppies“:[”必填字段。“]}” 即使我正在提供它。 GET工作正常,但我只有在数据库中手动编写的订单。

我们的项目是一个虚构的网上商店,您可以在其中将爱犬婴儿放入购物车中并订购。我们拥有的三个主要模型是“用户”,“订单”和“小狗”。因为每个订单都有一个幼犬列表,每个幼犬都有自己的数量,所以我们需要两者的中介模型,因为简单的ManyToManyField显然无法处理额外的列。这使事情变得更加复杂(至少对于Django新手而言)。

对于这种特殊情况,我在互联网上找不到任何东西。我一直在努力使它工作近一个星期,但我看不出我做错了什么。

models.py:

from django.db import models
from django.conf import settings
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver


class Puppy(models.Model):
    name = models.CharField(max_length=30)
    price = models.DecimalField(max_digits=6, decimal_places=2)
    image_url = models.CharField(max_length=200)
    age = models.IntegerField(null=True)
    weight = models.IntegerField(null=True)
    description_de = models.CharField(max_length=500, null=True)
    description_en = models.CharField(max_length=500, null=True)

    def __str__(self):
        return self.name


class Order(models.Model):
    total_price = models.DecimalField(max_digits=9, decimal_places=2)
    puppies = models.ManyToManyField(Puppy, through='PuppyOrder')
    date = models.DateTimeField(auto_now_add=True, blank=True)
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='orders')

    def __str__(self):
        return str(self.id)


class PuppyOrder(models.Model):
    order = models.ForeignKey(Order, on_delete=models.CASCADE)
    puppy = models.ForeignKey(Puppy, on_delete=models.CASCADE)
    amount = models.IntegerField()

    def __str__(self):
        return str(self.id)


class Address(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    country = models.CharField(max_length=30, blank=True)
    street = models.CharField(max_length=30, blank=True)
    zip = models.CharField(max_length=10, blank=True)
    city = models.CharField(max_length=30, blank=True)


@receiver(post_save, sender=User)
def create_user_address(sender, instance, created, **kwargs):
    if created:
        Address.objects.create(user=instance)


@receiver(post_save, sender=User)
def save_user_address(sender, instance, **kwargs):
    instance.address.save()

获取反应:

async function createOrder(order) {
  order = order.map(element =>
    element = {'puppy' : element.puppy.id, 'amount': element.amount}
  )
  let orderReq = {"total_price": "500.00", "puppies": order}
  console.log(JSON.stringify(orderReq))
  const res = await fetch(REACT_APP_BACKEND_URL + `/shop/orders/`, {
      method: 'POST',
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify({ orderReq })
    })
  return res.json()
}

Console.log结果为: {“总价”:“ 500.00”,“幼犬”:[{“幼犬”:2,“数量”:3},{“幼犬”:4,“数量” :4}]}

“ 500.00”只是一个占位符值。下一步将是找到一个计算total_price的地方。

views.py:

from shop.models import Puppy, Order
from django.contrib.auth.models import User
from rest_framework import permissions, status, viewsets, generics
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework.reverse import reverse
from rest_framework.exceptions import ValidationError
from rest_framework_jwt.serializers import VerifyJSONWebTokenSerializer
from .serializers import UserSerializer, UserSerializerWithToken, OrderSerializer, PuppySerializer


@api_view(['GET'])
def api_root(request, format=None):
    return Response({
        'users': reverse('user-list', request=request, format=format),
        'orders': reverse('order-list', request=request, format=format),
        'puppies': reverse('puppy-list', request=request, format=format),
    })


class OrderList(generics.ListCreateAPIView):
    print("Test")
    queryset = Order.objects.all()
    permission_classes = (permissions.AllowAny,)
    serializer_class = OrderSerializer

    def get_queryset(self):
        if self.request.user is None or self.request.user.is_anonymous:
            self.request.user = get_request_user_and_validate_token(self)
        return Order.objects.all().filter(user=self.request.user)

    def perform_create(self, serializer):
        print(self.request.data)
        if self.request.user is None or self.request.user.is_anonymous:
            self.reqest.user = get_request_user_and_validate_token(self)
        if serializer.is_valid():
            print('Creating new order...')
            serializer.create(user=self.request.user, puppies=self.request.data)
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


class OrderDetail(generics.RetrieveAPIView):
    permission_classes = (permissions.AllowAny,)
    queryset = Order.objects.all()
    serializer_class = OrderSerializer

    def get_queryset(self):
        if self.request.user is None or self.request.user.is_anonymous:
            self.request.user = get_request_user_and_validate_token(self)
        return Order.objects.all().filter(user=self.request.user)


class UserList(generics.ListAPIView):
    queryset = User.objects.all().select_related('address')
    serializer_class = UserSerializer


class UserDetail(generics.RetrieveAPIView):
    queryset = User.objects.all().select_related('address')
    serializer_class = UserSerializer


class PuppyList(generics.ListAPIView):
    permission_classes = (permissions.AllowAny,)
    queryset = Puppy.objects.all()
    serializer_class = PuppySerializer


class PuppyDetail(generics.RetrieveAPIView):
    permission_classes = (permissions.AllowAny,)
    queryset = Puppy.objects.all()
    serializer_class = PuppySerializer


def get_request_user_and_validate_token(self):
    print(self.request.user)
    token = self.request.META.get('HTTP_AUTHORIZATION', " ").split(' ')[1]
    data = {'token': token}
    try:
        valid_data = VerifyJSONWebTokenSerializer().validate(data)
        print(valid_data['user'])
        return valid_data['user']
    except ValidationError as v:
        print("validation error", v)

serializers.py

from rest_framework import serializers
from rest_framework_jwt.settings import api_settings
from django.contrib.auth.models import User
from django.db import models
from .models import Order, Puppy, PuppyOrder


class UserSerializer(serializers.ModelSerializer):
    orders = serializers.PrimaryKeyRelatedField(many=True, read_only=True)

    class Meta:
        model = User
        fields = ('id', 'username', 'orders')


class UserSerializerWithToken(serializers.ModelSerializer):
    # Code dealing with JWT token creation ... 


class PuppySerializer(serializers.ModelSerializer):
    description = serializers.SerializerMethodField()

    def get_description(self, puppy):
        return {'DE': puppy.description_de, 'EN': puppy.description_en}

    class Meta:
        model = Puppy
        fields = ('id', 'name', 'price', 'image_url', 'age', 'weight', 'description')


class PuppyOrderSerializer(serializers.ModelSerializer):
    puppy = serializers.ReadOnlyField(source='puppy.id')

    class Meta:
        model = PuppyOrder
        fields = ('puppy', 'amount')


class OrderSerializer(serializers.ModelSerializer):
    puppies = PuppyOrderSerializer(source='puppyorder_set', many=True)
    user = serializers.ReadOnlyField(source='user.username')
    total_price = "100.00"

    class Meta:
        model = Order
        fields = ('id', 'total_price', 'puppies', 'date', 'user')

任何帮助将不胜感激!

0 个答案:

没有答案