Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nullable source of ReadOnlyField #1306

Open
jennydaman opened this issue Oct 4, 2024 · 1 comment · May be fixed by #1307
Open

Nullable source of ReadOnlyField #1306

jennydaman opened this issue Oct 4, 2024 · 1 comment · May be fixed by #1307

Comments

@jennydaman
Copy link

jennydaman commented Oct 4, 2024

Describe the bug

I added a test for this bug to a fork. See jennydaman@c124c7a
To Reproduce

import uuid
from django.db import models
from rest_framework import serializers, viewsets
from tests import assert_schema, generate_schema
class Album(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
class Song(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    album = models.ForeignKey(Album, on_delete=models.CASCADE, null=True)
class SongSerializer(serializers.ModelSerializer):
    album_id = serializers.ReadOnlyField(source='album.id')
    class Meta:
        fields = ['id', 'album_id']
        model = Song
class SongModelViewset(viewsets.ModelViewSet):
    serializer_class = SongSerializer
    queryset = Song.objects.none()

Expected behavior

The album_id field should be nullable:

components:
  schemas:
    Song:
      type: object
      properties:
        album_id:
          type: string
          format: uuid
          readOnly: true
          nullable: true  # <-- expected to be in schema, actually missing
@jennydaman jennydaman linked a pull request Oct 4, 2024 that will close this issue
@jennydaman
Copy link
Author

jennydaman commented Oct 4, 2024

One down, 98 to go... similar bug occurs with HyperlinkedRelatedField

edit: to handle a case like

import uuid

from django.db import models
from rest_framework import serializers, viewsets

from tests import assert_schema, generate_schema


class Cubicle(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)


class Employee(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    cubicle = models.ForeignKey(Cubicle, on_delete=models.CASCADE, null=True)


class EmployeeSerializer(serializers.HyperlinkedModelSerializer):

    cubicle_url = serializers.HyperlinkedRelatedField(view_name='cubicle-detail', read_only=True)

    class Meta:
        fields = ['id', 'cubicle_url']
        model = Employee

In the example above, EmployeeSerializer.cubicle_url could be null but it is not explicitly created with allow_null=True. In this situation, drf-spectacular could figure this out using some magic involving django.urls.reverse and django.urls.resolve. Unfortunately I myself don't have the energy to contribute this fix (i.e. #1307 is ready to merge, it doesn't fix all related bugs but it does add something)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant