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

Model @property and SlugRelatedField not handled properly #943

Closed
sparktx-adam-gleason opened this issue Feb 21, 2023 · 4 comments
Closed
Labels
bug Something isn't working fix confirmation pending issue has been fixed and confirmation from issue reporter is pending

Comments

@sparktx-adam-gleason
Copy link

In v0.24.2 this works properly but v0.25.0 and onward broke how SlugRelatedField and @properties are being handled.

Describe the bug
SlugRelatedField that reference a model @property are not being handled.

While stepping through the functions on how this field is being resolved, I tracked down how this field is being handled in v0.25.0.

First, this logic was updated in v0.25.0 compared to v0.24.2.
https://github.com/tfranzel/drf-spectacular/blob/master/drf_spectacular/openapi.py#L663

The SlugRelatedField will get to this function.

def _follow_field_source(model, path: List[str]):

and will finally return this value at the end of traversal.

if isinstance(field_or_property, property):
return field_or_property.fget

Ultimately, this assertion is failing. https://github.com/tfranzel/drf-spectacular/blob/0.25.0/drf_spectacular/openapi.py#L544

Prior to this logic update, SlugRelatedFields used this logic to resolve. https://github.com/tfranzel/drf-spectacular/blob/0.24.2/drf_spectacular/openapi.py#L698-L699

To Reproduce

class MyModel(models.Model):
    label = models.CharField(
        max_length=100,
        unique=True,
    )

    class Meta:
        verbose_name = _("MyModel")
        verbose_name_plural = _("MyModels")

    def __str__(self):
        return self.label

    @property
    def property_field(self):
        return "42"

# How the field is defined in a Serializer
forty_two = serializers.SlugRelatedField(
    slug_field="property_field",
    read_only=True,
)

API Response

{
    "forty_two": "42"
}

Expected behavior
SlugRelatedFields that use @properties don't fail assertion and are resolved the same way they are handled in v0.24.2

@tfranzel
Copy link
Owner

tfranzel commented Feb 21, 2023

I see, will look into it. The change happened here #854.

Before, we had it hard-coded as string, so there was little chance of it breaking. Now, the introspection is assuming a model field, but it looks like a model property is also viable. We have the mechanics for that, but somehow it is not triggered.

I'm not exactly sure why you chose a slug here, but we should support it if it works. In the meantime, this should work too (if you add a return type property_field(self)-> str:):

forty_two = serializers.ReadOnlyField(source='property_field')

@tfranzel tfranzel added the bug Something isn't working label Feb 21, 2023
@sparktx-adam-gleason
Copy link
Author

@tfranzel For my use case, I am using SlugRelatedField because the actual property value is sourced from a ForeignKey related field to my model which I'm building a ModelSerializer for.

my_model.related_model.property_field

If I point the SlugRelatedField to a non-property field on the related model, I don't see an error in schema generation. This is to be expected because the assertion passes.

@tfranzel
Copy link
Owner

tfranzel commented Feb 21, 2023

For my use case, I am using SlugRelatedField because the actual property value is sourced from a ForeignKey related

Yes, I get that. ReadOnlyField also supports relations. What I meant was serializers.ReadOnlyField(source='related_model.property_field')

If I point the SlugRelatedField to a non-property field on the related model, I don't see an error in schema generation.

Sure, because the mechanics falsely expect a model field for SlugRelatedField target.

Anyways, this fix should do the trick. Please test it if you don't mind.

P.S. Please not note that this also requires a type hint on property_field to work properly.

@tfranzel tfranzel added the fix confirmation pending issue has been fixed and confirmation from issue reporter is pending label Feb 21, 2023
@tfranzel
Copy link
Owner

tfranzel commented Mar 4, 2023

closed with release 0.26.0

@tfranzel tfranzel closed this as completed Mar 4, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working fix confirmation pending issue has been fixed and confirmation from issue reporter is pending
Projects
None yet
Development

No branches or pull requests

2 participants