2016-01-20 4 views
3

Прежде всего, я очень новичок в Python/Django, но я использую другие технологии в течение многих лет.Наследование на Python или дополнительные свойства для огранки

В веб-сайт, где пользователи могут создавать публикации (давайте думать о Amazon, например), у меня есть Publication объект, который содержит основные вещи, такие как заголовок, детали, цена и т.д.

Я хочу, однако , чтобы включить определенные свойства, характерные для типа объекта (ткань имела бы размер, цвет, для мужчин/для женщин, автомобили имели бы бренд, модель, двигатель, трансмиссия и т. д.). Идея состоит в том, чтобы использовать Haystack/Elasticsearch для того, чтобы делать огранку на этих свойствах, в зависимости от того, что ищет пользователь.

Итак, вот базовая модель:

# main publication class 
class Publication(models.Model): 
    OBJECT_TYPE = (
     ('cloth', 'Cloth'), 
     ('electronics', 'Electronics'), 
     ('car', 'Cars'), 
    ) 
    object_type = models.CharField(max_length=30, 
            choices=OBJECT_TYPE, 
            default='electronics') 
    title = models.CharField() 
    details = models.CharField() 
    # other fields... 

# Haystack index 
class PublicationIndex(indexes.SearchIndex, indexes.Indexable): 
    text = indexes.CharField(document=True, use_template=True) 
    object_type = indexes.CharField(faceted=True, model_attr='object_type') 
    # other fields... 

Вопрос заключается в том, где я должен хранить эти другие свойства?

Одним из вариантов было бы иметь другой класс/модель с деталями и FK для публикации. Если да, то как мне тогда построить индекс? Другим вариантом было бы поставить все свойства для всех публикаций в модели Publication, что было бы самым простым, но, вероятно, не изящным.

Другим вариантом было бы наследование, чтобы иметь CarPublication, ClothPublication и т. Д. Если это так, будет вопрос, как мне обрабатывать основные вещи, чтобы избежать дублирования всех экранов по одному для каждого типа публикации.

У меня будет только 3 типа публикаций, и я не думаю, что добавлю больше, так что наследование, например, является выполнимым вариантом (у Amazon есть сотни категорий, поэтому они разные).

Какой был бы лучший подход?

FYI, используя Python 3, Django 1.9, Haystack 2.5-dev, Elasticsearch.

+0

[Джанго полиморфный] (https://github.com/chrisglass/django_polymorphic) обрабатывает это красиво –

+1

спасибо @IanPrice. Выглядит неплохо. Не стесняйтесь публиковать его в качестве ответа. –

ответ

2

django-polymorphic ручка это красиво.

Из документов:

from polymorphic.models import PolymorphicModel 

class Project(PolymorphicModel): 
    topic = models.CharField(max_length=30) 

class ArtProject(Project): 
    artist = models.CharField(max_length=30) 

class ResearchProject(Project): 
    supervisor = models.CharField(max_length=30) 


>>> Project.objects.create(topic="Department Party") 
>>> ArtProject.objects.create(topic="Painting with Tim", artist="T. Turner") 
>>> ResearchProject.objects.create(topic="Swallow Aerodynamics", supervisor="Dr. Winter") 
# Get polymorphic query results: 

>>> Project.objects.all() 
[ <Project:   id 1, topic "Department Party">, 
    <ArtProject:  id 2, topic "Painting with Tim", artist "T. Turner">, 
    <ResearchProject: id 3, topic "Swallow Aerodynamics", supervisor "Dr. Winter"> ] 
+0

Я пометил ваше решение как помощь из-за помощи, но я закончил тем, что объяснил в своем ответе. Я пробовал, и это работало, как шарм! Спасибо! –

+1

Очень приятно. На всякий случай, когда кто-либо рассматривает это в будущем, django-polymorphic позволяет фильтровать по типу модели как таковой - 'Project.objects.instance_of (ArtProject)' >>> '[] '(и вы также можете использовать' not_instance_of') –

1

OK. Даже когда @IanPrice ответ был очень хорошим и полезным, это то, что я в конечном итоге делает абстрактные базовые классы (see the documentation):

class BasePublication(models.Model): 
    class Meta: 
     abstract = True 
    # base properties 

class CarPublication(BasePublication): 
    # car-specific properties 

class ClothPublication(BasePublication): 
    # cloth-specific properties 

Причина являются:

  • В моем случае мне не нужно одновременно запрашивать обе вещи. Это возможно, но сложнее, поскольку они хранятся в разных таблицах.
  • Производительность, используя наследование, добавляет внутреннее соединение или дополнительные выделения. Это может быть неважно с объемом информации, которую я имею, но я сумасшедший в производительности, поэтому мне это не понравилось.
  • Простота, в моем случае с использованием наследования добавила больше проблем, чем то, что она решила, поэтому использование абстрактных классов было проще.