django-rest-framework
django-rest-framework copied to clipboard
Add custom_many_related_field to RelatedField
Note: Before submitting this pull request, please review our contributing guidelines.
Description
I was using PrimaryKeyRelatedField with source='item.services' but item
is a nullable entity in database when its null endpoint is raising 500 error on serialization. In order to fix that I have created custom SafeManyRelatedField wrapped get_attribute and returned empty_list in case attribute exceptions (Happens when accessing multiple relations). In implementation below you can see that Many init is copied from source directly so in order to make it dry I have opened this pr. I think this way would be easier to override with CustomManyRelatedField.
implementation:
class SafeManyRelatedField(ManyRelatedField):
"""
A custom ManyRelatedField that safely retrieves related fields.
This field is designed to handle cases where the related field might not exist,
returning an empty list when the related field is nullable or doesn't exist.
"""
def get_attribute(self, instance):
try:
return super().get_attribute(instance)
except AttributeError:
return []
class SafePrimaryKeyRelatedField(PrimaryKeyRelatedField):
"""
A custom PrimaryKeyRelatedField that safely retrieves related fields.
This field is designed to handle cases where the related field might not exist,
ensuring that it can be used safely without raising exceptions.
"""
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
@classmethod
def many_init(cls, *args, **kwargs):
list_kwargs = {'child_relation': cls(*args, **kwargs)}
for key in kwargs:
if key in MANY_RELATION_KWARGS:
list_kwargs[key] = kwargs[key]
return SafeManyRelatedField(**list_kwargs)
and usecase
services = SafePrimaryKeyRelatedField(
source='item.services',
many=True, read_only=True,
)
I'm not super sure about the approach or implementation so I will be waiting to know the insights from other maintainers
My view on almost all incoming PRs at the moment... https://github.com/encode/django-rest-framework/discussions/9270#discussioncomment-8828323
- What are the clearest ways we can update our contribution guidelines, and start minimizing code churn?
- How can we ensure that maintainers feel comfortable with helping us to say "no" as a default response?
(@ByK95 thanks for being invested in the project, it is appreciated even tho I'm trying to help us put the brakes on here.)