Опираясь на логику c Тимофей, предложенный здесь, я разработал своего рода обходной путь для поставленной мной проблемы.
Сначала модель, использующая модель Point в качестве поля выбора:
- Точка была переименована в 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)
в поле gdt не наследовать напрямую от точечной модели, чтобы я мог сделать следующее:
Здесь я не могу точно показать, что я сделал, но сначала я просто добавил еще одно поле с именем add_gdt, которое связано поле для известной модели местоположения.
И, как предложил Тимоте, если оно не выбрано, выберите поле gdt, если выбор не был сделан для gdt, чем добавьте поле add_gdt к известной базе данных местоположения как обычное связанное поле.
Сериализатор:
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')
здесь используйте gdt в качестве поля выбора, используя ленивый django для создания имен, соответствующих полю точечной модели, то есть поле выбора будет состоять из имен из известных точек в БД.
Как называется get_locations?
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():
qeuryset = KnownLocation.objects.all()
serialized_data = KnownLocationSerializer(qeuryset,
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()
Получить данные из qeuryset, сериализуйте его, ge t данных и создал из них работающий словарь со следующими данными:
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
Наконец, данные, используемые в представлении, с использованием функции возврата по имени для получения данных.
gdt = return_data_by_name(data=get_known_location(), query=location_name)