首页 > 解决方案 > 删除 Django Serializer 中的 Null 嵌套字段 --- 或如何使用 Null 进行迭代?

问题描述

我遇到的这个问题可能是一个 React 迭代问题,但我认为在 Django 内部的根部处理它会比在前端更有效。

可能的补救措施

  1. 如果不为空,则有条件地显示对象和参数的三元运算
  2. 从响应中删除空字段以避免需要通过 django 本身进行三元操作

虽然,首先,我似乎无法遍历我的回复。

我有一个双嵌套序列化程序:

型号

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)

class VideoProduct(models.Model):
    ...

class ImageProduct(models.Model):
    ...

class ProfileProduct(models.Model):
    profile = models.ForeignKey(Profile, on_delete=models.CASCADE)
    video_product = models.ForeignKey(VideoProduct, on_delete=models.CASCADE, blank=True)
    image_product = models.ForeignKey(VideoProduct, on_delete=models.CASCADE, blank=True)

    class Meta:
        unique_together = ('profile', 'video_product')
        unique_together = ('profile', 'image_product')

视图.py

class VideoProductViewSet(viewsets.ModelViewSet):
    queryset = VideoProduct.objects.all()
    serializer_class = VideoProductSerializer

class ImageProductViewSet(viewsets.ModelViewSet):
    queryset = ImageProduct.objects.all()
    serializer_class = VideoProductSerializer

class ProfileProductsViewSet(viewsets.ModelViewSet):
    queryset = ProfileProduct.objects.all()
    serializer_class = ProfileProductsSerializer

class ProfileBySlug(generics.ListAPIView):
    serializer_class = ProfileBySlugSerializer
    def get_queryset(self):
        slug = self.request.query_params.get('slug', None)
        queryset = Profile.objects.filter(slug=slug)
        if slug is not None:
            queryset = queryset.filter(slug=slug)
        return queryset

序列化器

class VideoProductSerializer(serializers.ModelSerializer):
    class Meta:
        model = VideoProduct
        fields = ['id', 'price']

class ImageProductSerializer(serializers.ModelSerializer):
    class Meta:
        model = ImageProduct
        fields = ['id', 'price']

class ProfileProductsSerializer(serializers.ModelSerializer):
    video_product = VideoProductSerializer(read_only=True)
    image_product = ImageProductSerializer(read_only=True)

    class Meta:
        model = ProfileProduct
        fields = ['id', 'video_product', 'image_product']
    
class ProfileBySlugSerializer(serializers.ModelSerializer):
    profile_products_set = serializers.SerializerMethodField('get_profile_products')

    def get_profile_products(self, profile):
        qs = ProfileProduct.objects.filter(profile=profile)
        serializer = ProfileProductsSerializer(instance=qs, many=True)
        return serializer.data

    class Meta:
        model = Profile
        fields = ['id', 'title', 'description', 'slug', 'image', 'status', 'profile_products_set']

问题是 ProfileProduct 只会与 video_product 或 image_product 有一个关联,但我的回答是这样的:

API 请求:

axios.get(`http://127.0.0.1:8000/api/v1/profile/`, {
  params: {
    slug: this.state.slug,
  }
})
  .then(res => {
      this.setState({ profile: res.data.results[0] });
      this.setState({ products: res.data.results[0].profile_products_set });
....

整体回复:

[{…}]
0:
    description: "Description"
    id: 1
    profile_products_set: Array(2)
      0:
        video_product: {id: 1, price: "0.00", status: true}
        image_product: null
        __proto__: Object
      1: {image_product: {…}, video_product: null}
      length: 3
      __proto__: Array(0)
    title: "Admin Title"
    __proto__: Object
    length: 1
    __proto__: Array(0)

我将 profile_products_set 的状态设置为:this.setState({ products: res.data.results[0].profile_products_set })

现在,当我在 React 中进行迭代时:

  { this.state.products.map(product =>
    <div>
      <li>{product.id}</li>
      <li>{product.price}</li>
    </div>
  )}

它是空白的,只有项目符号。

如上所述,我如何对其进行迭代并将其显示在前端,然后如果可能的话,将响应中的空字段一起删除,以避免需要根据产品类型进行三元操作

标签: reactjsdjangowebpackdjango-rest-framework

解决方案


您可以使用to_representation来覆盖序列化。然后,您可以删除具有None值的条目。

class ProfileProductsSerializer(serializers.ModelSerializer):
    video_product = VideoProductSerializer(read_only=True)
    image_product = ImageProductSerializer(read_only=True)

    class Meta:
        model = ProfileProduct
        fields = ['id', 'video_product', 'image_product']

    def to_representation(self, instance):
        data = super().to_representation()
        return {k: v for k, v in data.items() if v is not None}

推荐阅读