Django Rest Framework中POST请求中的相关字段ID

时间:2018-04-02 10:02:57

标签: python django django-models django-rest-framework django-views

我只使用相关字段class Resturant(models.Model): name = models.CharField(_('name'), max_length=100) class Menu(models.Model): resturant_id = models.OneToOneField(Resturant, related_name='resturant', on_delete=models.CASCADE) created_at = models.DateTimeField(auto_now=True) 创建对象。我搜索了很多,但无法得到答案。这是我的代码

models.py:

class MenuSerializer(serializers.ModelSerializer):
    resturant_id = serializers.PrimaryKeyRelatedField(read_only=True)

    class Meta:
        model = Menu
        fields = ['id', 'created_at', 'resturant_id']

serializers.py:

class CreateMenuAPIView(APIView):

    def post(self, request, *args, **kwargs):
        serializer = MenuSerializer(data=request.data)
        if serializer.is_valid(raise_exception=True):
            serializer.save()
            return Response(serializer.data, status=status.HTTP_200_OK)
        return Response(status=status.HTTP_400_BAD_REQUEST)

views.py:

{ "resturant_id": 2 }

我在POST请求中发送DETAIL: Failing row contains (14, 2018-04-02 09:36:43.261849+00, null). The above exception (null value in column "resturant_id" violates not-null constraint 时收到此错误。

src/main/resources/static

任何帮助将不胜感激!

5 个答案:

答案 0 :(得分:2)

您可以覆盖方法create for find Restaurant对象或创建(如果不存在)。并且只编辑序列化器。

serializer.py

  class MenuSerializer(serializers.ModelSerializer):
      resturant_id = serializers.PrimaryKeyRelatedField(read_only=True)

      class Meta:
          model = Menu
          fields = ['id', 'created_at', 'resturant_id']

      def create(self, validated_data):
        id_param = validated_data.pop('resturant_id')
        resturant = Resturant.objects.get_or_create(id=id_param)[0]
        menu = Menu.objtects.create(resturant_id=resturant.id)
        return menu

如果不起作用,您可以删除此行:

resturant_id = serializers.PrimaryKeyRelatedField(read_only=True)

答案 1 :(得分:0)

returant_id = serializers.PrimaryKeyRelatedField(read_only=True)

你可以尝试给read_only = False

你能检查一下拼写吗? returant_id用于序列化器字段,'s'缺失。 'resturant_id'用于字段列表

答案 2 :(得分:0)

您正在使用模型序列化程序并已覆盖'returant_id'。

class MenuSerializer(serializers.ModelSerializer):
    returant_id = serializers.PrimaryKeyRelatedField(queryset=Resturant.objects.all())

答案 3 :(得分:0)

尝试将序列化程序更改为

class MenuSerializer(serializers.ModelSerializer):
    resturant_id = serializers.PrimaryKeyRelatedField()

    class Meta:
        model = Menu
        fields = ['id', 'created_at', 'resturant_id']

如果read_only=True则不会写入数据库。

答案 4 :(得分:0)

对相关字段使用_id不是Django方式。所以我建议您更改以下代码 的 models.py

class Resturant(models.Model):
    name = models.CharField(max_length=100)


class Menu(models.Model):
    resturant = models.OneToOneField(Resturant, related_name='resturant', on_delete=models.CASCADE)
    created_at = models.DateTimeField(auto_now=True)


serializer.py

from datetime import datetime


class MenuSerializer(serializers.ModelSerializer):
    resturant_id = serializers.PrimaryKeyRelatedField(queryset=Resturant.objects.all())

    class Meta:
        model = Menu
        fields = ['id', 'created_at', 'resturant_id']

    def create(self, validated_data):
        return Menu.objects.create(resturant=validated_data['resturant_id'], created_at=validated_data.get('created_at', datetime.now()))


并且您的POST有效负载必须如此

{
"created_at":"2018-12-12T12:12:12",
"resturant_id":3
}

注意:
1.更改模型结构后不要忘记迁移
2.如果您尝试创建已使用Menu的{​​{1}}实例,则会引发异常