bdoubleu
bdoubleu

Reputation: 6107

DRF show ForeignKey field choices

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

Answers (1)

bdoubleu
bdoubleu

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

Related Questions