drf-writable-nested icon indicating copy to clipboard operation
drf-writable-nested copied to clipboard

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

Open eshxcmhk opened this issue 5 years ago • 6 comments

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

eshxcmhk avatar Feb 28 '20 08:02 eshxcmhk

same issue

dongnguyenvie avatar Apr 20 '20 18:04 dongnguyenvie

same issue

alyahmady avatar Apr 24 '20 09:04 alyahmady

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

dongnguyenvie avatar Apr 25 '20 17:04 dongnguyenvie

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

Leonardoperrella avatar Jun 16 '20 19:06 Leonardoperrella

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__"

mehdi-repo avatar Feb 27 '22 17:02 mehdi-repo

huh

gmalanchuk avatar Mar 11 '23 21:03 gmalanchuk