Django-rest-framework Create object with relationship many-to many

前端 未结 2 747
别那么骄傲
别那么骄傲 2020-12-19 06:21

I need to create object \"Tag\" with relationship many-to-many attached to object \"Task\".I have this code and don\'t understand why it doesn\'t work. I see error Cannot re

相关标签:
2条回答
  • 2020-12-19 06:42

    You need to handle the nested serializers creation in the serializers create method;

    As in here: http://www.django-rest-framework.org/api-guide/serializers/#writing-create-methods-for-nested-representations

    0 讨论(0)
  • 2020-12-19 06:42

    If you're not hung up on creating intermediate and other table records in one HTTP request. Otherwise you've got to handle nested representations.

    models.py:

    from django.db import models
    import django.urls
    import urllib
    
    class Product(models.Model):
        name = models.CharField(max_length=255)
    
        def get_absolute_url(self):
            return django.urls.reverse('app:product', args=(self.pk,))
    
        def __str__(self):
            return self.name
    
    class Size(models.Model):
        products = models.ManyToManyField(Product, through=ProductVariant,
            related_name='sizes', related_query_name='size')
        name = models.CharField(max_length=255)
    
        def __str__(self):
            return self.name
    
    class ProductVariant(models.Model):
        product = models.ForeignKey(Product, on_delete=models.CASCADE,
            related_name='productvariants', related_query_name='productvariant')
        size = models.ForeignKey('Size', on_delete=models.CASCADE,
            related_name='productvariants', related_query_name='productvariant')
    
        class Meta:
            unique_together = ('product', 'size')
    
        def __str__(self):
            return str(self.product) + ': ' + str(self.size)
    

    api.py:

    from rest_framework import routers, serializers, viewsets
    from app import models
    
    class ProductSerializer(serializers.ModelSerializer):
        class Meta:
            model = models.Product
            fields = ('id', 'name')
            read_only_fields = ('id',)
    
    class ProductViewSet(viewsets.ModelViewSet):
        queryset = models.Product.objects.all()
        serializer_class = ProductSerializer
    
    class SizeSerializer(serializers.ModelSerializer):
        class Meta:
            model = models.Size
            fields = ('id', 'name')
            read_only_fields = ('id',)
    
    class SizeViewSet(viewsets.ModelViewSet):
        queryset = models.Size.objects.all()
        serializer_class = SizeSerializer
    
    class ProductVariantSerializer(serializers.ModelSerializer):
        product = serializers.PrimaryKeyRelatedField(
            queryset=models.Product.objects.all())
        size = serializers.PrimaryKeyRelatedField(
            queryset=models.Size.objects.all())
        class Meta:
            model = models.ProductVariant
            fields = ('id', 'product', 'size')
            read_only_fields = ('id',)
    
    class ProductVariantViewSet(viewsets.ModelViewSet):
        queryset = models.ProductVariant.objects.all()
        serializer_class = ProductVariantSerializer
    
    router = routers.DefaultRouter()
    router.register(r'products', ProductViewSet)
    router.register(r'sizes', SizeViewSet)
    router.register(r'productvariants', ProductVariantViewSet)
    
    api_urlpatterns = ([
        url('', include(router.urls)),
    ], 'api')
    urlpatterns += [
        url(r'^api/', include(api_urlpatterns)),
    ]
    

    After that you can

    POST /api/products/ {name: ...}
    POST /api/sizes/ {name: ...}
    POST /api/productvariants/ {product: productId, size: sizeId}
    
    0 讨论(0)
提交回复
热议问题