Reputation: 6107
What's the best way to go about letting a frontend user know about ForeignKey field choices using Django Rest Framework? In the Browsable API these fields have a dropdown widget with all the existing objects as choices.
A custom metadata class could return the available choices for each field but the request could be very slow if there are millions of objects.
Suppose you have a model similar to below and there's only 5 unit objects. How would you go about listing the unit choices?
class OrderLine(models.Model):
order = models.ForeignKey(Order)
product = models.ForeignKey(Product)
unit = models.ForeignKey(Unit)
Upvotes: 4
Views: 1358
Reputation: 6107
I ended up implementing a custom metadata class that adds foreign key choices to an OPTIONS request based on the serializer attribute extra_choice_fields
. This way you can choose which fields to provided choices for on each serializer and which to not include (ex. exclude fields with a lot of objects).
from rest_framework.metadata import SimpleMetadata
from rest_framework.relations import ManyRelatedField, RelatedField
from django.utils.encoding import force_text
class ChoicesMetadata(SimpleMetadata):
def get_field_info(self, field):
field_info = super().get_field_info(field)
if (isinstance(field, (RelatedField, ManyRelatedField)) and
field.field_name in getattr(field.parent.Meta, 'extra_choice_fields', [])):
field_info['choices'] = [{
'value': choice_value,
'display_name': force_text(choice_name, strings_only=True)
} for choice_value, choice_name in field.get_choices().items()]
return field_info
Upvotes: 3