【问题标题】:Cannot assign "OrderedDict()...: "..." must be a "..." instance无法分配“OrderedDict()...:“...”必须是“...”实例
【发布时间】:2021-02-16 09:03:45
【问题描述】:

我正在使用 Django Rest & React 制作一个网络应用程序。

models.py

class Bike(models.Model):
    RegoNumber = models.CharField(max_length=10)
    RegoExpiry = models.DateField(auto_now=False,auto_now_add=False)  
    LastRentedDate = models.DateField(auto_now=False,auto_now_add=False)  

    def __str__(self):
        return self.RegoNumber

class Hire(models.Model):
    # StartRentDate = models.DateField(auto_now=False,auto_now_add=False,null=True)
    # EndRentDate = models.DateField(auto_now=False,auto_now_add=False,null=True)
    KMsLastShown = models.IntegerField()
    KMsToLastService = models.IntegerField()
    # ServiceHistory = models.FileField()
    LastService = models.IntegerField()
    RentalPrice = models.FloatField()
    Bike = models.OneToOneField(Bike,on_delete=models.CASCADE,null=True,related_name='Bike')

    def __str__(self):
        return f'Bikes hire data'

序列化器.py

from rest_framework import serializers, fields
from drf_writable_nested.serializers import WritableNestedModelSerializer
from .models import Hire, Bike

class BikeSerializer(serializers.ModelSerializer):
    class Meta:
        model = Bike
        fields = '__all__'

class HireSerializer(WritableNestedModelSerializer):
    Bike = BikeSerializer(required=False)

    class Meta:
        model = Hire
        fields = '__all__'

index.js(反应)

import ReactDOM from 'react-dom'
import {useReducer} from 'react'
import Cookies from 'js-cookie'

ReactDOM.render(
    <React.StrictMode>
        <App/>
    </React.StrictMode>,
document.getElementById('root')
)


function App(){
    function sendData(e) {
        e.preventDefault()
        const csrftoken = Cookies.get('csrftoken');

        const dataToSend = {
            method: 'POST',
            headers: {'Content-Type':'application/json',
            'Accept': 'application/json',
            'X-CSRFToken': csrftoken        
        },
            body: JSON.stringify({              
                KMsLastShown: 0,
                KMsToLastService: 50,
                LastService: 50,
                RentalPrice: 40,
                Bike: {
                    RegoNumber: 'Hello',
                    RegoExpiry: '2020-05-11',
                    LastRentedDate: '2020-07-07'
                }
            })
  
        }
        console.log('Working')
        fetch('/api/hire/',dataToSend)
        .then(response => response.json())
        .then(json => console.log(json))
    }
    return (
        <>
          <button onClick={function(e){sendData(e)}}></button>
        </>
    )
}

views.py

from django.shortcuts import render
from rest_framework import generics, status
from rest_framework.views import APIView
from rest_framework.response import Response
from .models import Bike,Hire
from .serializers import BikeSerializer, HireSerializer

# Create your views here.

class BikeView(generics.CreateAPIView):
    queryset = Bike.objects.all()
    serializer_class = BikeSerializer

    def get(self,request,format=None):
        queryset = Bike.objects.all()
        serializer = BikeSerializer(queryset,many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)        

    def post(self,request,format=None):
        # if not self.request.session.exists(self.request.session.session_key):
        #     self.request.session.create()

        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            RegoNumber = serializer.data.get('RegoNumber')
            RegoExpiry = serializer.data.get('RegoExpiry')
            LastRentedDate = serializer.data.get('LastRentedDate')
            queryset = Bike.objects.filter(RegoNumber=RegoNumber)
            if queryset.exists():
                bike_to_update = queryset[0]
                bike_to_update.RegoExpiry = RegoExpiry
                bike_to_update.LastRentedDate = LastRentedDate
                bike_to_update.save(update_fields=['RegoExpiry','LastRentedDate'])
                return Response(BikeSerializer(bike_to_update).data, status=status.HTTP_200_OK)
            else:
                bike = Bike(RegoExpiry=RegoExpiry,RegoNumber=RegoNumber,LastRentedDate=LastRentedDate)
                bike.save()
                return Response(BikeSerializer(bike).data,status=status.HTTP_202_ACCEPTED)
            return Response(status=status.HTTP_400_BAD_REQUEST)

class HireView(generics.ListCreateAPIView):
    queryset = Hire.objects.all()
    serializer_class = HireSerializer

    # This POST request gives the error, if I remove the POST method I am able to manually 
    # make a POST request from the ListCreateAPIView url

    def post(self,request):
        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            KMsLastShown = serializer.data.get('KMsLastShown')
            KMsToLastService = serializer.data.get('KMsToLastService')
            LastService = serializer.data.get('LastService')
            RentalPrice = serializer.data.get('RentalPrice')
            Bike = serializer.data.get('Bike')
            # Make this filter based on Bike Rego Number
            queryset = Hire.objects.filter(KMsLastShown=KMsLastShown)
            if queryset.exists():
                hire_to_update = queryset[0]
                hire_to_update.KMsLastShown = KMsLastShown
                hire_to_update.KMsToLastService = KMsToLastService
                hire_to_update.LastService = LastService
                hire_to_update.RentalPrice = RentalPrice
                hire_to_update.Bike = Bike
                hire_to_update.save(update_fields=['Bike','KMsLastShown','KMsToLastService','LastService','RentalPrice'])
                return Response(HireSerializer(hire_to_update).data, status=status.HTTP_200_OK)
            else:
                hire = Hire(Bike=Bike,KMsLastShown=KMsLastShown,KMsToLastService=KMsToLastService,LastService=LastService,RentalPrice=RentalPrice)
                hire.save()
                return Response(HireSerializer(hire).data,status=status.HTTP_202_ACCEPTED)
            return Response(status=status.HTTP_400_BAD_REQUEST)

当我尝试在 Hire 的 index.js 中发出 Post 请求时,它返回错误 Cannot assign "OrderedDict([('RegoNumber', 'Hello'), ('RegoExpiry', '2020-05-11'), ('LastRentedDate', '2020-07-07')])": "Hire.Bike" must be a "Bike" instance.

如果我在我的 Post 请求中将 Bike 留空,一切正常,但是当我尝试添加它时,我得到了错误。

此外,在我在 HireView 中添加 def post 逻辑之前,我能够在 CreateAPIView 中手动发布自行车,但是一旦我添加它,当我尝试手动发布自行车时,它会给我同样的 Cannot assign "OrderedDict([('RegoNumber', 'Hello'), ('RegoExpiry', '2020-05-11'), ('LastRentedDate', '2020-07-07')])": "Hire.Bike" must be a "Bike" instance. 错误

提前致谢,

【问题讨论】:

  • 我对 react.js 了解不多,但是您可以执行如下循环:- if "your_instance" : 然后显示 post.. else 留空。

标签: python reactjs django rest django-rest-framework


【解决方案1】:

我猜你可以采取两种不同的方法:

  1. 如果您覆盖自行车序列化程序的 to_representation 方法 并明确指定键值,序列化器的数据将是 一个普通的字典。
  2. 不要使用serializer.data,而是使用serializer.validated_data

【讨论】:

    【解决方案2】:

    解决方案是创建一个 Bike 实例...

                # Start of Hire serializer
                StartRentDate = serializer.data.get('Hire').get('StartRentDate')
                EndRentDate = serializer.data.get('Hire').get('EndRentDate')
                KMsLastShown = serializer.data.get('Hire').get('KMsLastShown')
                KMsToLastService = serializer.data.get('Hire').get('KMsToLastService')
                LastService = serializer.data.get('Hire').get('LastService')
                RentalPrice = serializer.data.get('Hire').get('RentalPrice')
                hire = Hire(StartRentDate=StartRentDate,EndRentDate=EndRentDate,KMsLastShown=KMsLastShown,KMsToLastService=KMsToLastService,LastService=LastService,RentalPrice=RentalPrice)
                hire.save()
    

    我需要创建一个租用实例并将其保存为我的 Bike 模型中的租用字段

    【讨论】:

      猜你喜欢
      • 2011-02-22
      • 2018-06-03
      • 1970-01-01
      • 1970-01-01
      • 2018-07-28
      • 1970-01-01
      • 2020-12-05
      • 2021-11-18
      相关资源
      最近更新 更多