2016-10-10 4 views
1

Итак, у меня есть ситуация в Django, где у меня есть модель S, которая может иметь ряд атрибутов, но я понятия не имею, какие атрибуты будут релевантными/требуемыми. Чтобы справиться с этим, я думаю о создании дополнительной модели SAttrib, которая имитирует запись словаря и получает доступ к ней через свойство метаданных. Смотри ниже.Django: доступ к таблице через диктофонный интерфейс

class S(models.Model):                                    
    id = models.AutoField(primary_key=True) 
    name = models.CharField(max_length=128, blank=True, null=True) 
    description = models.CharField(max_length=128, blank=True, null=True) 
    created_date = models.DateTimeField(auto_now_add=True, auto_now=False) 
    modified_date = models.DateTimeField(auto_now_add=False, auto_now=True) 
    def __unicode__(self): 
     return smart_unicode(self.name) 
    class Meta: 
     db_table = "stest" 
    def _get_metadata(self): 
     class AD(dict): 
      def __init__(self, id): 
       self.id = id 
      def __getitem__(self, key): 
       return SampleAttrib.objects.filter(sample_id=self.id, attrib_key=key).get().attrib_value 

     return AD(self.id) 

    metadata = property(_get_metadata) 

class SampleAttrib(models.Model): 
    s_id = models.ForeignKey("S") 
    attrib_key = models.CharField(max_length=128) 
    attrib_value = models.TextField() 
    class Meta: 
     db_table = 's_attrib' 
     unique_together = (('s_id', 'attrib_key'),) 

Я хотел бы сделать так, чтобы у меня были доступ к атрибутам, хранящимся в SAttrib, путем реализации его как свойства. Поэтому я хотел бы быть в состоянии получить доступ к значениям, как так:

y = S.objects.get() 
y.metadata["foo"] 

Но тогда это становится беспорядком и требует много дополнительного кода для настройки и сохранения объектов/содержит т.д.

s = S.objects.get() 
s.metadata["foo"] = "spam" 

..... 

Есть лучший способ структурирования этого или чего-то уже в Django, которого я не хватает?

Все предложения приветствуются ....

Благодаря

+1

Если вы используете Django 1.8+ и PostgreSQL, посмотрите на HStoreField, это даст вам в значительной степени то, что вы хотите достичь в рамках одной и той же модели. https://docs.djangoproject.com/en/1.8/ref/contrib/postgres/fields/#hstorefield –

+1

Я бы, вероятно, использовал просто текстовое поле под названием «метаданные» и использовал json для сериализации/десериализации сохраненного dict. Если вам нужно запускать необработанные запросы по ключам/значениям, это не идеально, потому что только последняя версия mysql имеет функции для управления json. Не уверен относительно других двигателей БД. –

+1

Я пытаюсь сделать это как независимое, насколько это возможно, бэкэнда, но это определенно решает проблему, если я использую hstore на postgresql. Такой же вопрос для json. –

ответ

1

Не много не так с идеей, за то, что вы, кажется, сделали это напрасно сложно с использованием функции _get_metadata кроме. Возможно, у вас тоже есть проблема с производительностью.

Этот вид подхода с двумя столами является довольно популярным во многих веб-приложениях, когда вы не знаете заранее, какие пары имя/значение вы будете хранить в своей таблице. Однако практика теперь снижается благодаря решению nosql и большинству РСУБД, которые теперь поддерживают типы данных JSON.

Django имеет встроенную поддержку превосходного поля JSONB Postgresql. Для других баз данных, проверенные и проверенные JSONFields доступны, поэтому использование JSONFields даст вам довольно хорошее независимое от базы данных решение.

Смежные вопросы