如果POST参数中已包含相关模型的ID,则Django REST框架会要求其输入

时间:2019-08-30 11:53:19

标签: django django-rest-framework

我正在使用Django及其REST_Framework,将一个对象添加到我的POSTGRES-11数据库中,该数据库的模型(团队)通过ForeignKey关系与另一个模型(国家)相关。我随发布请求发送的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).

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

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

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

models.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

serializers.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']

views.py:

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

我应该注意,当我尝试通过“ / api / register / team”中提供的HTML表单添加Django时,Django可以很好地工作,但是当它通过外部发布请求接收到JSON时,Django不能很好地工作。

我已经坚持了好几天,所以非常感谢您的帮助。


@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"}

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

1 个答案:

答案 0 :(得分:0)

首先,您应该在default="", blank=True模型的country字段中删除Team。 FK字段默认不应包含空字符串。如果您希望您的国家/地区可能无法设置,请使用blank=True, null=True。但是,如果每个Team都必须有一个国家/地区,则不要添加任何内容。

您可以做两件事:

  • 要么在'country_id'的字段中使用TeamSerializer,然后在JSON中将字段作为country_id传递。您需要同时执行这两项操作,在JSON中传递country_id,但在序列化程序中将country作为字段无效。

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

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