【问题标题】:Django : TypeError: int() argument must be a string, a bytes-like object or a number, not 'Driver'Django:TypeError:int() 参数必须是字符串、类似字节的对象或数字,而不是“驱动程序”
【发布时间】:2022-01-15 22:05:11
【问题描述】:

在创建车辆时,在 driver_id 中,我必须传递一个对象 Drive 的实例(所以当我传递一个数字时,我会在序列化程序中找到一个具有此 ID 的对象并传递它,否则它会给出一个错误,即需要传递实例)。

但是当我想在某个对象vehicle/1/上显示信息时,如果这个对象有一个对象实例的driver_id字段会报错,但是当它为null时,一切都很好

车型:

class Vehicle(models.Model):
    driver_id = models.ForeignKey(Driver,
                                  related_name='vehicles',
                                  on_delete=models.PROTECT,
                                  null=True,
                                  blank=True)
    make = models.CharField(max_length=255)
    model = models.CharField(max_length=255, verbose_name='Model')
    plate_number = models.CharField(max_length=255, verbose_name='Plate Number')
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='Created')
    updated_at = models.DateTimeField(auto_now=True, verbose_name='Updated')

    def __str__(self):
        return self.model

网址:

urlpatterns = [
    path('vehicle/', VehicleListView.as_view()),
    path('vehicle/<int:vehicle_id>/', VehicleView.as_view())
]
class VehicleListView(APIView):

    def get(self, request):
        vehicles = Vehicle.objects.all()
        serializer = VehicleSerializer(vehicles, many=True)
        return Response({"vehicles": serializer.data})

    def post(self, request):
        vehicles = request.data.get('vehicle')
        serializer = VehicleSerializer(data=vehicles)
        if serializer.is_valid(raise_exception=True):
            vehicle_saved = serializer.save()
        context = {
            'success': f'Vehicle {vehicle_saved.plate_number} created successfully'
        }
        return Response(context)
class VehicleView(APIView):
    def get(self, request, vehicle_id):
        vehicle = Vehicle.objects.filter(id=vehicle_id)
        serializer = VehicleSerializer(vehicle, many=True)
        return Response({"vehicle": serializer.data})

    def put(self, request, vehicle_id):
        vehicle_saved = get_object_or_404(Vehicle.objects.all(), pk=vehicle_id)
        data = request.data.get('vehicle')
        serializer = VehicleSerializer(instance=vehicle_saved, data=data, partial=True)
        if serializer.is_valid(raise_exception=True):
            vehicle_saved = serializer.save()
        return Response({
            "success": f"Vehicle '{vehicle_saved.plate_number}' updated successfully"
        })

    def delete(self, request, vehicle_id):
        vehicle = get_object_or_404(Vehicle.objects.all(), pk=vehicle_id)
        vehicle.delete()
        return Response({
            "message": f"Vehicle with id `{vehicle_id}` has been deleted."
        }, status=204)
class VehicleSerializer(serializers.Serializer):
    driver_id = serializers.IntegerField(required=False)
    make = serializers.CharField(max_length=255)
    model = serializers.CharField(max_length=255)
    plate_number = serializers.CharField(max_length=255)

    def create(self, validated_data):
        validated_data['driver_id'] = Driver.objects.get(id=validated_data['driver_id'])
        return Vehicle.objects.create(**validated_data)

    def update(self, instance, validated_data):
        if "driver_id" in validated_data:
            instance.driver_id = Driver.objects.get(id=validated_data['driver_id'])
        instance.make = validated_data.get('make', instance.make)
        instance.model = validated_data.get('model', instance.model)
        instance.plate_number = validated_data.get('plate_number', instance.plate_number)

        instance.save()
        return instance

驱动模型:

class Driver(models.Model):
    first_name = models.CharField(max_length=255, verbose_name='First Name')
    last_name = models.CharField(max_length=255, verbose_name='Last Name')
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='Created')
    updated_at = models.DateTimeField(auto_now=True, verbose_name='Updated')

    def __str__(self):
        return self.first_name

司机观看次数:

class DriverView(APIView):
    def get(self, request,  driver_id):
        driver = Driver.objects.filter(id=driver_id)
        serializer = DriverSerializer(driver, many=True)
        return Response({"driver": serializer.data})

    def put(self, request, driver_id):
        saved_driver = get_object_or_404(Driver.objects.all(), pk=driver_id)
        data = request.data.get('driver')

        serializer = DriverSerializer(instance=saved_driver, data=data, partial=True)
        if serializer.is_valid(raise_exception=True):
            saved_driver = serializer.save()
        return Response({
            "success": f"Driver '{saved_driver.first_name}' updated successfully"
        })

    def delete(self, request, driver_id):
        driver = get_object_or_404(Driver.objects.all(), pk=driver_id)
        driver.delete()
        return Response({
            "message": f"Driver with id `{driver_id}` has been deleted."
        }, status=204)


class DriverListView(APIView):
    def get(self, request):
        qp = request.query_params

        if not qp:
            drivers = Driver.objects.all()
        else:
            created_gte, created_lte = 'created_at__gte', 'created_at__lte'

            timezone = created_gte if created_gte in qp else created_lte

            time = qp.get(timezone)
            time = map(int, time.split('-')[::-1])

            if timezone == created_gte:
                drivers = Driver.objects.filter(created_at__gte=datetime(*time))
            else:
                drivers = Driver.objects.filter(created_at__lte=datetime(*time))

        serializer = DriverSerializer(drivers, many=True)
        return Response({"driver": serializer.data})

    def post(self, request):
        drivers = request.data.get('driver')
        serializer = DriverSerializer(data=drivers)
        if serializer.is_valid(raise_exception=True):
            driver_saved = serializer.save()
        return Response({
            'success': f'Driver {driver_saved.first_name} created successfully'
        })

驱动序列化器:

class DriverSerializer(serializers.Serializer):
    first_name = serializers.CharField(max_length=255)
    last_name = serializers.CharField(max_length=255)

    def create(self, validated_data):
        return Driver.objects.create(**validated_data)

    def update(self, instance, validated_data):
        instance.first_name = validated_data.get('first_name', instance.first_name)
        instance.last_name = validated_data.get('last_name', instance.last_name)

        instance.save()
        return instance

请求:

  "vehicle":
  {
    "driver_id": 1,
    "make": "5000г",
    "model": "Merc",
    "plate_number": "AE 1111 AB"
  }
}

错误信息:

TypeError: int() argument must be a string, a bytes-like object or a number, not 'Driver'

【问题讨论】:

  • 你有驱动的序列化器吗?
  • 你的Driver班级在哪里?
  • @ShashikamalRC 没有
  • @shivankgtm 更新
  • @РоманЯровой 你能添加完整的回溯吗?

标签: python django-rest-framework


【解决方案1】:

您需要传递对象的 id,以便替换所有出现的以下内容:

instance.driver_id = Driver.objects.get(id=validated_data['driver_id'])

通过

instance.driver_id = Driver.objects.get(id=validated_data['driver_id']).id

【讨论】:

  • 是的,现在它显示有关对象的信息,但是当我想更新对象并在 driver_id 中指定一个数字时,它会抛出错误 ValueError: Cannot assign "1": "Vehicle.driver_id"必须是“驱动程序”实例。
  • 这有点好笑。您有 ID,并通过该 ID 在数据库中查找对象,并使用该对象检索其.. ID?呜? ))
  • @alexakarpov 我已经在电脑前6个多小时了,我的脑袋已经是一团糟,所以对我来说这不是很有趣))
  • @РоманЯровой "t throws an error ValueError: Cannot assign "1": "Vehicle.driver_id" must be a "Driver" instance. "这是因为在您的 Vehicle 类中,您必须在与 Driver 的外键关系。你也可以粘贴车辆类
  • @shivankgtm 是的,完成)
【解决方案2】:

伙计,你有很多东西搞糊涂了)

对于初学者,删除中的这一行:

    vehicle = get_object_or_404(Vehicle.objects.all(), pk=vehicle_id)

应该是

vehicle = get_object_or_404(Vehicle, pk=vehicle_id)

objects.all() 为您提供了一个完整的 quesryset,您在这里不需要。

接下来,create中的这一行:

validated_data['driver_id'] = Driver.objects.get(id=validated_data['driver_id'])

您的请求数据中已经有 driver_id。您的 API 的客户端想要删除的内容。绝对没有理由重新分配该 valid_data 字典中的值。更糟糕的是,你正在这样做:

  1. 使用 API 调用中的 driver_id 从 db 加载驱动程序模型实例。好的,有道理。没有意义的是您为什么要替换 driver_id 和 id。如果您需要将 id 镜像到模型中的另一个字段,那么至少不要改变它。但我的猜测是,你根本不需要这个 driver_id。
  2. 然后您将通过 id(在 db 中)= drived_id(在请求中)查找 object,并将该对象分配给 dict 中的键“driver_id” - 然后尝试创建一个您刚刚查找的新实例!现在这个没有意义了。

【讨论】:

  • "接下来,create 中的这一行:validated_data['driver_id'] = Driver.objects.get(id=validated_data['driver_id'])" - 是的,但如果我不添加这个,但是直接发送 id,当我输出所有汽车时,它会给出一个错误,即期望一个实例 Driver 但传递了 int
  • 那是错误的做法——您没有解决问题,而是混淆了它,结果使问题变得更糟。
猜你喜欢
  • 2017-02-15
  • 1970-01-01
  • 2019-05-18
  • 1970-01-01
  • 2019-08-15
  • 2016-12-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多