【问题标题】:django - "Incorrect type. Expected pk value, received str" errordjango - “类型不正确。预期的 pk 值,收到 str”错误
【发布时间】:2015-08-26 04:23:57
【问题描述】:

我的 django-rest-framework 我有以下模型:

基本上每个行程都有一个最终目的地,并且可以有多个中间目的地。

models.py:

class Destination(models.Model):
    name=models.CharField(max_length=30)

class Ride(models.Model):
    driver = models.ForeignKey('auth.User', related_name='rides_as_driver')
    destination=models.ForeignKey(Destination, related_name='rides_as_final_destination')
    leaving_time=models.TimeField()
    num_of_spots=models.IntegerField()
    passengers=models.ManyToManyField('auth.User', related_name="rides_as_passenger")
    mid_destinations=models.ManyToManyField(Destination, related_name='rides_as_middle_destination')

serializers.py - RideSerializer

class RideSerializer(serializers.ModelSerializer):
    driver = serializers.ReadOnlyField(source='driver.user.username')

    class Meta:
        model = Ride
        fields = ('driver', 'destination', 'leaving_time',
                  'num_of_spots', 'passengers', 'mid_destinations')
        read_only_fields = ('driver', 'passengers', 'mid_destinations')

问题是 - 当我尝试 POST 到 /rides/ 以添加行程时 - 例如 {destination=LA, leaving_time=19:45, num_of_spots=4}

我收到错误"destination":["Incorrect type. Expected pk value, received str."]}

几个问题:

  • 这是什么错误?如果我在 Ride 模型中有一个目的地作为外键,这是否意味着我要添加的目的地必须已经在 Destinations 表中?

  • 如何修复此错误?

【问题讨论】:

    标签: django serialization foreign-keys django-rest-framework


    【解决方案1】:

    问题是您将相关Destination 对象的name 传递到序列化程序,而不是传递Destination 对象的pk/id。所以 Django REST 框架看到了这一点并开始抱怨,因为它无法将 LA 解析为对象。

    听起来您实际上可能正在寻找 a SlugRelatedField,它允许您通过 slug(在本例中为 LA)而不是它们的主键来识别对象。

    【讨论】:

    • 感谢您的回答。我还有一个问题——如果我像你说的那样使用 SlugRelatedField,在创建之后会有一个带有目的地的 Ride,并且 Destination 对象不存在于 Destination 表中,对吧?问题不是外键关系吗?我的意思是,外键不应该是对另一个表中现有对象的引用吗?再次感谢
    • @OfekAgmon DRF 不处理自动创建相关对象。如果目的地不存在,您需要 override .create 创建目的地。
    • 知道了。而且,对于 SlugRelatedField,我想知道两个场景: 1. 我发布“LA”(LA 在 Destinations 表中不存在)并将其添加到 Ride 表中,对吗? 2. 如果我使用“NY”发布,并且“NY”已经在 Destination 表中,是否会在“NY”Ride 对象和“NY”Destination 对象之间创建连接?再次非常感谢
    • @OfekAgmon SlugRelatedField 在数据库中查找具有该 slug 的对象,所以是的,这应该像您描述的那样工作。如果你想open a chat这个,我们可以更详细地讨论。
    • 谢谢!就我而言,我必须从 SlugRelatedField 中删除 read_only/many 字段并添加 queryset=Destination.objects.all() 字段才能使其工作。
    【解决方案2】:

    Angular/Django Rest 框架

    我在尝试发布一个包含一些数组值的字段的表单数据时遇到了类似的问题。事实证明,我在 Angular 前端的帖子标题中使用了错误的内容类型。我只需要注释掉 Content-Type。

      Post(endpoint, postData) {
        let auth = `Bearer ${this.token}`;
        let headers = new HttpHeaders({
          // "Content-Type": "application/x-www-form-urlencoded",
          Authorization: auth
        });
        let fullurl = `${this.baseUrl}${endpoint}`;
       .....
      ....
    }
    

    【讨论】:

      【解决方案3】:

      每当我们尝试将外键引用添加到实例时,Django 和 Django Rest Framework 之间存在细微差别

      假设我们想要将用户引用添加到另一个数据库表

      姜戈

      在 Django 中,我们引用用户的整个实例,如下所述

      user = request.user
      

      Django 休息框架

      但是在 DRF 中,如果我们遵循相同的程序,我们会得到类似的错误

      类型不正确。预期的 pk 值,收到的 str/用户类型

      为了克服这个错误,我们需要引用表的主键(这里id是PK)

      user = request.user.id
      

      【讨论】:

        猜你喜欢
        • 2021-09-06
        • 2020-09-09
        • 2018-10-05
        • 1970-01-01
        • 2017-06-14
        • 2021-10-11
        • 2021-05-17
        • 2021-07-03
        • 1970-01-01
        相关资源
        最近更新 更多