Relying on the logic Timothe proposed here I have constructed a kind of workaround
to the problem I presented.
First, the model using the Point model as choices field:
- Point has been renamed to KnownLocation.
class Mission(models.Model):
id = models.UUIDField(primary_key=False, default=uuid.uuid4, editable=False)
mission_name = models.CharField(name='MissionName',
verbose_name="Mission Name",
max_length=255,
blank=False,
help_text="Enter the mission's name",
unique=True,
primary_key=True
# We want to be able to query missions not let them be confused with other missions.
)
uav_lat = models.FloatField(name="UavLatitude",
verbose_name="UAV Latitude",
unique=False, max_length=255, blank=False,
help_text="Enter the location's Latitude, first when extracting from Google Maps.",
default=DEFAULT_VALUE)
uav_lon = models.FloatField(name="UavLongitude",
verbose_name="UAV Longitude",
unique=False, max_length=255, blank=False,
help_text="Enter the location's Longitude, second when extracting from Google Maps.",
default=DEFAULT_VALUE)
gdt = models.CharField(verbose_name='Locations',
max_length=20)
the gdt field does not inherit directly from the point model, in order for me to do the following:
Here I can't show exactly what I did, but at first, I just added another field called
add_gdt, which is a related field to the knownlocation model.
And as Timothe suggested, if it's none choose the gdt field, if no choice was made
on gdt, than add add_gdt field to the knownlocation db as regular related field.
Serializer:
from Utils.APIConsts.Custom import get_locations, known_locations_data
from django.utils.functional import lazy
from rest_framework.fields import ChoiceField, DictField
from rest_framework.serializers import HyperlinkedModelSerializer
from .models import Mission
class MissionSerializer(HyperlinkedModelSerializer):
gdt = ChoiceField(choices=lazy(get_locations, tuple)())
locations = DictField(known_locations_data)
class Meta:
model = Mission
fields = ('Area', 'gdt', 'MissionName', 'UavLatitude', 'UavLongitude', 'UavElevation',
'locations')
use gdt here as choices field, using django's lazy to create names corrsepnding to the field of the point model, meaning, the choices field will be composed of the names of the known points in the db.
What is the get_locations being called?
Utils.APIConsts.Custom.py :
def get_locations():
"""
Returns the names of the locations in KnownLocation model.
"""
return [loc.Name for loc in KnownLocation.objects.all()]
def get_known_location():
queryset = KnownLocation.objects.all()
serialized_data = KnownLocationSerializer(queryset,
many=True)
locations_data = serialized_data.data
to_repr_dict = repack(data=locations_data, return_type='dict')
return to_repr_dict
known_locations_data = get_known_location()
Get the data being from the queryset, serialize it, get the data and created workable dictionary from it, with the following:
def repack(data, return_type=DICT):
"""
This function receives a list of ordered dictionaries to to unpack and reassign every dict to it's first value.
data: the data to unpack
return_type: specify the returned data type; dict or list.
'dict' is default
"""
try:
repacked_dict = {next(iter(d.values())): d for d in data}
if return_type is DICT:
return repacked_dict
elif return_type is LIST:
repacked_list = list(repacked_dict.items())
return repacked_list
raise TypeError('requested return type is not valid.')
except:
raise TypeError('data is not a list.')
def return_data_by_name(data, query) -> list:
"""
This function receive a nested dictionary and matches a given the query to the keys of the dictionary,
If there's a match, than that match is returned.
:param dict data:
:param str query:
"""
for name, values in data.items():
if query.lower() in name.lower():
values = list(values.values())
return values
Finally, The data being used in the view, using the return by name function to get the data.
gdt = return_data_by_name(data=get_known_location(), query=location_name)