beda-software / drf-writable-nested

Writable nested model serializer for Django REST Framework
Other
1.08k stars 116 forks source link

The `.update()` method does not support writable nested fields by default #104

Open eshxcmhk opened 4 years ago

eshxcmhk commented 4 years ago

Hi. I am having some trouble with object update. Models

from django.db import models

class A(models.Model):
    uid = models.CharField(max_length=300)

class B(models.Model):
    name = models.CharField(max_length=100, null=True, blank=True)
    record = models.ForeignKey(A, on_delete=models.CASCADE, related_name='items')

Serializers

from rest_framework import serializers
from drf_writable_nested import UniqueFieldsMixin , WritableNestedModelSerializer

class BSerializer(serializers.ModelSerializer):
    class Meta:
        model = B
        fields = ('pk', 'name')

class ASerializer(UniqueFieldsMixin, WritableNestedModelSerializer):
    class Meta:
        model = A
        fields = ('pk', 'uid', 'items',)

    items = BSerializer(many=True)

JSON

{
    "id":54,
    "uid":"主记录",
    "items":[
        {
            "record_id": 54,
            "id":1,
            "name":"更新条目"
        },
        {
            "record_id": 54,
            "name":"新增条目"
        }
    ]
}

When i submit a PUT request, I get an error saying:

AssertionError: The `.update()` method does not support writable nested fields by default.
Write an explicit `.update()` method for serializer '... BSerializer'

I tried extend WritableNestedModelSerializer for BSerializer, but not works!

Django===2.2.9 Python===3.7.4 Djangorestframework===3.11.0 drf-writable-nested===0.5.4

dongnguyenvie commented 4 years ago

same issue

alyahmady commented 4 years ago

same issue

dongnguyenvie commented 4 years ago

same issue

I resolve by this way. U can ref https://github.com/dongnguyenvie/be_audiovyvy_django/blob/master/apps/posts/api/serializers.py#L57

Leonardoperrella commented 4 years ago

It worked for me like this

--serializers.py--

class ProductsSerializer(serializers.ModelSerializer):
    class Meta:
        model = Products
        fields = ('name', 'code', 'price')

class VendorsSerializer(WritableNestedModelSerializer,
                        serializers.ModelSerializer):
    products = ProductsSerializer(source='vendor', many=True)
    class Meta:
        model = Vendors
        fields = ('name', 'cnpj', 'city', 'products')

--models.py--

class Vendors(models.Model):
    name = models.CharField('Name', max_length=50)
    cnpj = models.CharField('CNPJ', max_length=14, unique=True, validators=[validate_cnpj])
    city = models.CharField('City', max_length=100, blank=True)

    class Meta:
        verbose_name = "Vendor"
        verbose_name_plural = "Vendors"

    def __str__(self):
        return self.name

class Products(models.Model):
    name = models.CharField('Name', max_length=60)
    code = models.CharField('Code', max_length=13)
    price = models.DecimalField('Price',
                                max_digits=15,
                                decimal_places=2,
                                default=0.00,
                                validators=[MinValueValidator(Decimal("0.01"))])
    vendor = models.ForeignKey('Vendors', on_delete=models.CASCADE, related_name='vendor')

    class Meta:
        verbose_name = "Product"
        verbose_name_plural = "Products"

    def __str__(self):
        return self.name
mehdi-repo commented 2 years ago

It's worked Correctly for me

from rest_framework import serializers from .models import Task, TaskComponent, TaskDetail, Traking from django.contrib.auth.models import User from drf_writable_nested import WritableNestedModelSerializer

class TrackingSerializer(serializers.ModelSerializer):
    class Meta:
        model = Traking
        fields = "__all__"
class TaskComponentSerializer(serializers.ModelSerializer):
    class Meta:
        model = TaskComponent
        fields = "__all__"
class TaskDetailSerializer(serializers.ModelSerializer):
    class Meta:
        model = TaskDetail
        fields = "__all__"
        read_only_fields = ('signature',)
        extra_kwargs = {
           "task_detail_discription": {'write_only': True},
        }
class TaskSerializer(WritableNestedModelSerializer,
                        serializers.ModelSerializer):
    tasks_detail=TaskDetailSerializer(many=True)
    task_component=TaskComponentSerializer(many=True)
    task_tracking=TrackingSerializer(many=True)
    class Meta:
        model=Task
        fields = "__all__"
gmalanchuk commented 1 year ago

huh