首页 > 解决方案 > 当 POST 参数中已经存在相关模型的 id 时,Django REST Framework 会询问它

问题描述

使用 Django 及其 REST_Framework,我试图将一个对象添加到我的 POSTGRES-11 数据库中,其模型(团队)通过 ForeignKey 关系与另一个模型(国家)相关。我与 post 请求一起发送的 JSON 看起来像这样,其中为国家提供的数字应该是它的 id。

name:"test"
is_onsite:true
status:"PAID"
institution:"testU"
country:2

但随后 Django 返回以下错误:

IntegrityError at /api/register/team/
null value in column "country_id" violates not-null constraint
DETAIL:  Failing row contains (28, , f, PENDING, , null).

我尝试发送相同的 json,将 'country' 替换为 'country_id',但我遇到了同样的错误。

我已经尝试过Here给出的解决方案,但是 Django 返回这个 JSON 而不是添加对象:

{
    "country": [
        "This field is required."
    ]
}

模型.py:

class Country(models.Model):
    name = models.CharField(max_length=255)
    flag = models.ImageField()
    class Meta:
        verbose_name_plural = 'Countries'

    def __str__(self):
        return self.name

class Team(models.Model):
    name = models.CharField(max_length=255, default="", blank=True)
    is_onsite = models.BooleanField(default=False)
    status = models.CharField(max_length=50, choices=TEAM_STATUS_CHOICES, default='PENDING')
    institution = models.CharField(max_length=255, default="")
    country = models.ForeignKey(Country, on_delete=models.CASCADE, default="", blank=True)

    def __str__(self):
        return self.name

序列化程序.py:

class CountrySerializer(serializers.ModelSerializer):
    class Meta:
        model = Country 
        fields = '__all__'

class TeamSerializer(serializers.ModelSerializer):
    class Meta:
        model = Team 
        fields = ['name', 'is_onsite', 'status', 'institution', 'country']

视图.py:

class TeamCreateView(CreateAPIView):
    queryset = Team.objects.all()
    serializer_class = TeamSerializer

我应该注意到,当我尝试通过“/api/register/team”提供的 HTML 表单添加 Django 时,Django 工作得非常好,但当它通过外部 post 请求接收 JSON 时却不行。

我已经被困了好几天了,所以你的帮助将不胜感激。


@dirkgroten 我忘了提,我通过将以下代码段添加到我的 TeamSerializer 并尝试在我的 POST 请求中发送“countryId”(而不是“country_id”)来完成前一件事,但它仍然不起作用。这个片段:

countryId = serializers.PrimaryKeyRelatedField(queryset=Country.objects.all())
    def create(self, validated_data):
        print(validated_data)
        return Team.objects.create(
            name=validated_data['name'],
            is_onsite=validated_data['is_onsite'],
            status=validated_data['status'],
            institution=validated_data['institution'],
            country=validated_data['countryId']
        )

至于后一种情况,我将这 country = CountrySerializer(many=False)一行添加到我的代码中,并发送了如下所示的 JSON,但我仍然得到“此字段是必需的”JSON。我的 POST JSON:

name:"test"
is_onsite:true
status:"PAID"
institution:"testU"
country:{"name": "Test"}

即使国家“测试”存在于我的数据库中,它仍然无法添加团队。

标签: djangodjango-rest-framework

解决方案


首先,您应该删除模型default="", blank=Truecountry字段Team。FK 字段不应默认为空字符串。如果您希望您所在国家/地区的可能性“未设置”,请使用blank=True, null=True. 但是,如果每个Team人都必须有一个国家,那就不要添加任何东西。

你可以做两件事:

  • 您可以'country_id'在您的字段中使用并像在 JSON 中TeamSerializer一样传递该字段。country_id您需要同时执行这两项操作,传入country_id您的 JSON,但country作为序列化程序中的字段将不起作用。

    fields = ['name', 'is_onsite', 'status', 'institution', 'country_id']
    
  • 或者您添加country = CountrySerializer(many=False)到您的TeamSerializer但随后在您的 json 中,您需要在您的请求中嵌套一个国家/地区,它将创建国家/地区对象:

    {'name': 'test',
     ...
     'country': {
         'name': 'Angola'
      }
    }
    

推荐阅读