У меня есть собственный класс (и, возможно, более скоро), который я хотел бы аккуратно хранить на некоторых своих моделях в Django.
Класс выглядит примерно так:
class BBOX(object):
def __init__(self, min_x, min_y, max_x, max_y, srs_code, **kwargs):
self.min_x = min_x
self.max_x = max_x
self.min_y = min_y
self.max_y = max_y
self._srs_code = get_srs_code(srs_code)
self._srs_identifier = 'EPSG:{}'.format(self.srs_code)
self._srs = SRS(self.srs_code)
У класса очень много свойств и вспомогательных функций, которые мы используем для безопасной обработки объектов ограничивающего прямоугольника в нашем приложении на основе геопространственных данных. В коде мы безопасно передаем их, зная, что они будут просты в использовании и прекрасно взаимодействуют с остальным нашим кодом. Как правило, мы никогда не хотим работать с ограничивающим прямоугольником в нашем коде, который не представлен экземпляром этого класса, за исключением случаев, когда мы обязательно должны передать список или что-то подобное (например, когда мы сериализуем значения в JSON, YAML или что-то подобное).
Некоторые из наших моделей Django имеют значения, связанные с BBOX. В настоящее время все эти разрозненные модели должны вручную определить поля, которые им необходимы для представления BBOX. Для удобства мы добавили некоторые вспомогательные свойства к некоторым из них для преобразования в наш объект. Например:
class Layer(PolymorphicModel):
name = models.CharField(max_length=255, blank=True, null=True)
title = models.CharField(max_length=255, blank=True, null=True)
parent_layer = models.ForeignKey('self', blank=True, null=True)
min_x = models.FloatField()
min_y = models.FloatField()
max_x = models.FloatField()
max_y = models.FloatField()
srs_code = models.IntegerField()
@property
def bbox(self):
return BBOX(self.min_x, self.min_y, self.max_x, self.max_y, self.srs_code)
Очевидно, что это может привести к значительному дублированию кода, если нам потребуется добавить набор полей в каждую модель, которая может иметь BBOX. Это может затруднить поддержание и изменение.
Какой лучший способ справиться с чем-то подобным? Я подумал о создании новой таблицы для BBOX:
class DjangoBbox(Model):
min_x = models.FloatField()
min_y = models.FloatField()
max_x = models.FloatField()
max_y = models.FloatField()
srs_code = models.IntegerField()
Тогда я мог бы добавить ссылки на внешние ключи, где это необходимо, но что-то в этой идее пахнет мной. Что-то не так с этой идеей? Первое, о чем я могу подумать, это то, что теоретически несколько ключей могут указывать на одну и ту же запись DjangoBbox, и изменения одного из них будут отражаться в обоих, даже если они непреднамеренные.