我可以在Django REST的模型中使用ModelViewSet来发布和获取self的父对象吗?

2024-04-23 20:57:43 发布

您现在位置:Python中文网/ 问答频道 /正文

您好,我有以下结构: 类别(models.Model):

model.py

    """Class to represent the category of an Item. Like plants, bikes..."""
    name = models.TextField()

    description = models.TextField(null=True)

    color = models.TextField(null=True)

    # This will help to anidate categories
    parent_category = models.ForeignKey(
        'self',
        on_delete=models.SET_NULL,
        null=True,
    )

然后我将其序列化: serializers.py

class CategorySerializer(serializers.ModelSerializer):
    """Serializer for Category."""
    
    class Meta: # pylint: disable=too-few-public-methods
        """Class to represent metadata of the object."""
        model = Category
        fields = ['id', 'name', 'description', 'color', 'parent_category']

我创建了我的尾端 views.py

class CategoryViewset(viewsets.ModelViewSet): # pylint: disable=too-many-ancestors
    """API Endpoint to return the list of categories"""
    queryset =  Category.objects.all()
    serializer_class = CategorySerializer
    pagination_class = None

好吧,这似乎与提出post请求的预期一样有效,例如发送以下内容:

 {
    "name": "Plants",
    "description": null,
    "color": "#ef240d",
    "parent_category": 1
  }

但是,当我提出这个请求时,我希望看到父类别,而不必执行两个请求。因此,我从其他问题中发现,我可以使用外部库: serializer.py

from rest_framework_recursive.fields import RecursiveField
class CategorySerializer(serializers.ModelSerializer):
    """Serializer for Category."""
    parent_category = RecursiveField(many=False)
    
    class Meta: # pylint: disable=too-few-public-methods
        """Class to represent metadata of the object."""
        model = Category
        fields = ['id', 'name', 'description', 'color', 'parent_category', 'category_name']

然后它似乎起了作用:

  {
    "id": 2,
    "name": "Flowers",
    "description": null,
    "color": "#ef240a",
    "parent_category": {
      "id": 1,
      "name": "Plants",
      "description": "something",
      "color": "#26def2",
      "parent_category": null,
    },
  },

但是,当我现在尝试发布时,它将不起作用,因为它似乎期望一个对象,而不仅仅是我在前端可以使用的ID:

{
  "parent_category": {
    "non_field_errors": [
      "Invalid data. Expected a dictionary, but got int."
    ]
  }
}

有可能在我的ModelSerializer中以某种方式混合这两种方法吗


Tags: ofthetonamepyidmodelmodels
1条回答
网友
1楼 · 发布于 2024-04-23 20:57:43

您可以自定义ModelViewSet以使用两个序列化程序而不是一个序列化程序。比如说

class CategoryViewset(viewsets.ModelViewSet):
    queryset = Category.objects.all()
    serializer_class = CategorySerializer
    pagination_class = None
    
    def create(self, request):
        new_category = CategoryCreateSerializer(data=request.data)
        if new_category.is_valid:
            return Response(CategoryRetrieveSerializer(new_category).data)

相关问题 更多 >