beda-software / drf-writable-nested

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

Allow re-assigning of related object, disable creation. #100

Open striveforbest opened 4 years ago

striveforbest commented 4 years ago

I am trying to achieve re-assigning of the related nested object, while not allowing the creation of new related objects in case object with the provided id doesn't exist.

Here is my model:

class WorkMarket(models.Model):
    name = models.CharField(unique=True, max_length=255, verbose_name='Name')

Child serializer:

class MarketSerializer(UniqueFieldsMixin, serializers.ModelSerializer):
    class Meta:
        model = WorkMarket
        fields = (
            'id',
            'name',
        )
        read_only_fields = ('name', )

Parent serializer:

class WorkSerializer(NestedUpdateMixin):
    market = MarketSerializer()

    class Meta:
        model = Work
        fields = (
            'id',
            'market',
            'artist',
        )

Here is what my detail endpoint response looks like:

Request: GET http://localhost:8000/api/v1/works/works/163672

{
    "id": 163672,
    "artist": 1104,
    "market": {
        "id": 1,
        "name": "Primary"
    }
}

I am able to re-assign the market using the following:

Request: http://localhost:8000/api/v1/works/works/163672/

{
    "artist": 1104,
    "market": {
        "id": 2
    }
}

Response:

{
    "id": 163672,
    "artist": 1104,
    "market": {
        "id": 2,
        "name": "Secondary"
    }
}

However, I want to disable creation of new the nested object (market), only re-assigning should work. The below should not work:

Request: PUT http://localhost:8000/api/v1/works/works/163672/

{
    "artist": 1104,
    "market": {
        "id": 5  # NON-EXISTENT ID
    }
}

How would I achieve that? I wasn't able to find a way to disable the creation. Separately, seems like it ignores the fact that WorkMarket.name is a unique field (and i already have an instance with name == '').

Here is the response I am getting:

IntegrityError at /api/v1/works/works/163672/
duplicate key value violates unique constraint "workmarket_name_key"
DETAIL:  Key ("name")=() already exists.
uripeled2 commented 3 years ago

If you only went re-assigning you don't need to use this library, just use ModelSerializer.