Skip to content
Advertisement

Django rest framework, field that is a choice or text

Is there a way to create a field which is A text field, but, with choices. that the choices are the field existing objects? And if the word passed in is not in the existing data, add it?

I’ve looked across all the internet for a field like this or example of it, either in Django or the rest framework, but could not find one.

My use for it, for example, would be:

class Point(models.Model):
    location_name = models.TextField(verbose_name="Location name",
                                     unique=True,
                                     # This would include the existing names.
                                     choices=,
                                     )
    latitude = models.FloatField(name="GDT1Latitude",
                                 verbose_name="GDT 1 Latitude",
                                 unique=False, max_length=255, blank=False,
                                 help_text="Enter the location's Latitude, first when extracting from Google Maps.",
                                 default=DEFAULT_VALUE)
    longitude = models.FloatField(name="GDT1Longitude",
                                  verbose_name="GDT 1 Longitude",
                                  unique=False, max_length=255, blank=False,
                                  help_text="Enter the location's Longitude, second when extracting from Google Maps.",
                                  default=DEFAULT_VALUE)

So, It could be used when making a post request instead of already typing the latitude, longitude It would be fetched from the exsiting object.

Advertisement

Answer

At Database level, a field can not be both a “choices”-like and a free text field.

What you actually want is an abstraction on top of a couple of hidden DB fields

class Book(models.Model):
   THEME_CHOICES = (
     ('Horror', 'Horror'),
     ('Romance', 'Romance')
   )
   _theme = models.CharField(choices=THEME_CHOICES, max_length=258, null=True, blank=True)
   _other_theme = models.CharField(max_length=258)

   @property
   def theme(self):
      if self._other_theme:
          return self._other_theme
      else:
          return self._theme

This is just the first “DB-level”, but you’ll also need to custom ‘.save()’ method, add a setter with @property.setter.

Another option would be to write this abstraction at Form level instead of Model level.

Advertisement