You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django多对多关系的反序列化及指定JSON结构实现方法

How to Generate the Desired JSON Structure for Category & Product Many-to-Many Relationship

Hey there! Let's walk through how to build that exact JSON output you need. First, I spotted a small typo in your Product model's many-to-many field—you currently have:

category = models.name = models.ManyToManyField(Category)

That should be simplified to:

category = models.ManyToManyField(Category)

This fixes the invalid field definition and ensures the many-to-many relationship works correctly.

Now, here are two reliable approaches to generate your target JSON:

Approach 1: Use Django REST Framework (DRF) Serializers

If you're using DRF (the standard tool for Django API development), this is the cleanest method:

Step 1: Create Serializers

Create a serializers.py file in your app with these serializers:

from rest_framework import serializers
from .models import Category, Product

# Serializer to format product data into your desired "name" and "code" fields
class ProductMiniSerializer(serializers.ModelSerializer):
    code = serializers.CharField(source='product_code')  # Maps product_code to "code" in JSON

    class Meta:
        model = Product
        fields = ['name', 'code']

# Serializer for categories, including related products
class CategorySerializer(serializers.ModelSerializer):
    # Use source='product_set' to access the reverse many-to-many relationship
    products = ProductMiniSerializer(many=True, source='product_set')

    class Meta:
        model = Category
        fields = ['id', 'name', 'description', 'products']

Step 2: Build a View to Return the JSON

Add this view to your views.py:

from rest_framework.response import Response
from rest_framework.decorators import api_view
from .models import Category
from .serializers import CategorySerializer

@api_view(['GET'])
def categories_with_products(request):
    # Use prefetch_related to avoid N+1 database queries (critical for performance)
    categories = Category.objects.prefetch_related('product_set').all()
    serializer = CategorySerializer(categories, many=True)
    # Wrap the serialized data in the "categories" top-level key
    return Response({"categories": serializer.data})

Note: Your sample JSON shows a single products object per category, but since it's a many-to-many relationship, a category can have multiple products. The above code returns products as an array of objects (which is more logical for this relationship). If you specifically need one product per category (e.g., the first one), replace many=True with a custom serializer method:

# Inside CategorySerializer
products = serializers.SerializerMethodField()

def get_products(self, obj):
    product = obj.product_set.first()
    if product:
        return ProductMiniSerializer(product).data
    return {}

Approach 2: Manual JSON Construction (No DRF)

If you don't want to use DRF, you can manually build the dictionary and return it as JSON:

Add this view to your views.py:

from django.http import JsonResponse
from .models import Category

def categories_with_products(request):
    categories_list = []
    # Prefetch related products to optimize database queries
    categories = Category.objects.prefetch_related('product_set').all()

    for category in categories:
        # Get the first product (adjust this if you need all products)
        product = category.product_set.first()
        product_data = {
            "name": product.name,
            "code": product.product_code
        } if product else {}

        category_data = {
            "id": category.id,
            "name": category.name,
            "description": category.description,
            "products": product_data
        }
        categories_list.append(category_data)

    return JsonResponse({"categories": categories_list})

Key Notes for Both Approaches

  • Always use prefetch_related('product_set') when querying categories—this fetches all related products in a single query instead of one query per category (avoids the N+1 performance issue).
  • Handle cases where a category has no products (return an empty products object instead of causing an error).

内容的提问来源于stack exchange,提问作者amit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 04:41:13