Не знаю, является ли сортировка оптимальной. Но это, безусловно, хорошая отправная точка. Со случайным набором данных я вижу:
Второе решение было найдено с помощью модели смешанного целочисленного программирования . Это оказалось оптимальным (но я добавил ограничение, что значения растут по строкам и столбцам).
Не лучше ли было бы это отношение выразить как отношение внешнего ключа «один ко многим» к таблице Friends
? Я понимаю, что myFriends
- это просто строки, но я думаю, что лучшим дизайном было бы создание модели Friend
, в которой MyClass
содержали связь с внешним ключом для итоговая таблица.
Мое решение, может быть, оно помогает кому-то:
import json
from django.db import models
class ExampleModel(models.Model):
_list = models.TextField(default='[]')
@property
def list(self):
return json.loads(self._list)
@list.setter
def list(self, value):
self._list = json.dumps(self.list + value)
Твердо помня об этом, давайте сделаем это! Как только ваши приложения достигают определенной точки, денормализация данных становится очень распространенным явлением. Если все сделано правильно, это может сэкономить множество дорогостоящих поисков в базе данных за счет немного дополнительной обработки.
Чтобы вернуть список
имен друзей, нам нужно создать собственный класс Django Field, который будет возвращать list при доступе.
Дэвид Крамер разместил руководство по созданию SeperatedValueField в своем блоге. Вот код:
from django.db import models
class SeparatedValuesField(models.TextField):
__metaclass__ = models.SubfieldBase
def __init__(self, *args, **kwargs):
self.token = kwargs.pop('token', ',')
super(SeparatedValuesField, self).__init__(*args, **kwargs)
def to_python(self, value):
if not value: return
if isinstance(value, list):
return value
return value.split(self.token)
def get_db_prep_value(self, value):
if not value: return
assert(isinstance(value, list) or isinstance(value, tuple))
return self.token.join([unicode(s) for s in value])
def value_to_string(self, obj):
value = self._get_val_from_obj(obj)
return self.get_db_prep_value(value)
Логика этого кода имеет дело с сериализацией и десериализацией значений из базы данных в Python и наоборот. Теперь вы можете легко импортировать и использовать наше настраиваемое поле в классе модели:
from django.db import models
from custom.fields import SeparatedValuesField
class Person(models.Model):
name = models.CharField(max_length=64)
friends = SeparatedValuesField()
Вы можете сохранить практически любой объект, используя поле рассола Django, как этот фрагмент:
Помните, что в конечном итоге это должно оказаться в реляционной базе данных. Таким образом, использование отношений - это наиболее распространенный способ решения этой проблемы. Если вы абсолютно настаиваете на хранении списка в самом объекте, вы можете сделать его, например, разделенным запятыми и сохранить его в строке, а затем предоставить функции доступа, которые разбивают строку на список. При этом вы будете ограничены максимальным количеством строк, и вы потеряете эффективные запросы.
Использование отношения «один-ко-многим» (FK от Friend к родительскому классу) сделает ваше приложение более масштабируемым (поскольку вы можете тривиально расширить объект Friend с помощью дополнительных атрибутов, помимо простого имени). Таким образом, это лучший способ
class Course(models.Model):
name = models.CharField(max_length=256)
students = models.ManyToManyField(Student)
class Student(models.Model):
first_name = models.CharField(max_length=256)
student_number = models.CharField(max_length=128)
# other fields, etc...
friends = models.ManyToManyField('self')