6

ПРОБЛЕМА: Проблема, которую я имею получает цену опциона в Выбор модели. Это связано с тем, что в зависимости от того, какие другие опции находятся в одной и той же тележке, для генерации общего количества будут использованы разные цены. Мне нужна помощь с набором запросов, который дает мне цену Опция, если у опции есть effector_option, которая сама по себе находится в той же тележке, которая используется, в противном случае используйте Вариант с только полем опций.Джанго: Проверка, существует ли объект в QuerySet (IF ELSE)

TempName App модель состоит из:

class Section(models.Model): 
    title = models.CharField(max_length=20) 
    description = models.CharField(max_length=100) 
    temp = models.ForeignKey(TempName, null=False) 
    def __str__(self): 
     return self.title 
    def get_options(self): 
     return self.option_set.all() 

class Option(models.Model): 
    name = models.CharField(max_length=120) 
    section = models.ForeignKey(Section, null=False) 
    def __str__(self): 
     return self.name 
    def get_variations(self): 
     return self.variation_set.all() 

class Variation(models.Model): 
    name = models.CharField(max_length=60, blank=True, unique=True) 
    price = models.DecimalField(max_digits=5, decimal_places=2) 
    option = models.ForeignKey(Option, null=False) 
    effector_option = models.ForeignKey(Option, null=True, blank=True, related_name='option_effected') 
    def __str__(self): 
     return self.name 

Там может быть много Разделы на одной странице. Каждая Раздел может содержать множество Опции, которые впоследствии могут быть выбраны пользователем. Выбранный вариант пойдет в корзину, которая будет использоваться для создания общей цены.

В Вариация модели, опция поле просто говорит мне, какая опция Вариация принадлежит. Поле effector_option в пределах . Вариация модель, однако, будет использована тележкой.

Пользователю будет позволено выбрать любое количество Options, однако, в зависимости от параметров выбранного пользователя, другие параметры могут отображать Variation цены, где effector_option был ранее выбран.

Корзина App модель состоит из:

class Cart(models.Model): 
    owner = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True) 
    creation_date = models.DateTimeField(verbose_name='creation date') 
    checked_out = models.BooleanField(default=False, verbose_name='checked out') 
    class Meta: 
     verbose_name = 'cart' 
     verbose_name_plural = 'carts' 
     ordering = ('-creation_date',) 
    def __str__(self): 
     return unicode(self.creation_date) 
    def get_selections(self): 
     return self.selection_set.all() 


class Selection(models.Model): 
    cart = models.ForeignKey(Cart) 
    option = models.ForeignKey(Option) 
    @property 
    def price(self): 
     return 10 

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

, что я пытался:

Получить все варианты опции. Затем проведите каждую переменную и проверьте, содержится ли Variation.effector_option в той же Корзина. Если это отображает эту цену, в противном случае отобразите цену в пределах вариации, где Variation.effector_option будет null/не установлен.

Я обнаружил, что за каждую вызывают более 26 запросов в корзине. Нуждается ли в этой схеме db более нормализовать или это достаточно хорошо для этого простого проекта?

+0

Читайте о том, как запросить (операторов набора запросов), а не в цикле. – philipxy

+0

@philipxy Да, я сделал это. Однако проблема, с которой я сталкиваюсь, запрашивает запрос, затем запрашивает этот результат. Я еще раз прочитал эту часть документов, возможно, я что-то пропустил. –

+1

Google 'stackoverflow.com django запрос результата другого запроса'. – philipxy

ответ

3

Я обнаружил, что для каждого выбора в корзине вызывается более 26 запросов. Нуждается ли в этой схеме db более нормализовать или это достаточно хорошо для этого простого проекта?

Я укушу, потому что считаю, что решение этого - разработка программного обеспечения. Проблема здесь не нормализация, и это не Django. Как вы решили организовать проблему. Я предполагаю, что вы попали в несколько ловушек, о которых я расскажу, когда мы пойдем. Прежде всего, давайте получить некоторые определения прямо здесь, начиная с вашим собственным ...

  • Раздела - группа опций
  • Опции - Ценовое
  • Изменения - попытка смоделировать варианты, влияют на другие варианты

Теперь у нас есть эта проблема? Некоторые из моих Option вариантов могут быть использованы с другими вариантами Option и влияют на цену! Хаос! Нам нужно Variation для предоставления мета-правил для их взаимодействия. Больше запросов! Больше логики! Может быть ...

Ловушка 1

Позволить путь вещи смотреть на экране управлять вашей модели данных

Я угадывание здесь, но использование слов Section и Option макияж мне кажется, что вы организуете экран, а не базу данных. Чаще всего предприятия имеют модели, которые выглядят следующим образом ...

  • Product - Что-то мы продаем (name, base_price, options, option_sets)
  • OptionSet - группы опций, которые идут вместе, как пакет услуг! Подумайте об экономии (name, group, options, price, optionset_exclusions, option_exclusions)
  • Option - а-ля карт варианты (name, group, price)
  • Purchase - Что кто-то хочет купить (product, options , optionsets)

Теперь вы можете сказать: «Как насчет моих разделов!» Разделы могут быть чем-то легким, как повешение куска метаданных с OptionSet и Option по номеру group с типом CharField. При рендеринге в шаблоне вы можете группировать опции/опции вместе на group. Вы можете использовать exclusions, чтобы люди не выбирали конфликтующие Option и OptionSets для Product.Теперь весь этот shebang можно наброситься на страницу с помощью всего лишь 3 запросов (с правильным использованием prefetch_related), и выбранные Options/OptionSets можно просто добавить вместе, чтобы получить детерминированную цену.

Trap 2

Позволить, как вы хотите, чтобы работать предотвратить его от работы на всех

Теперь перед запуском залп «Это не может работать для меня, Я снежинка! »(Здесь давно). Часто мы обнаруживаем, что способ, которым мы хотим что-то работать, мешает ему работать.

Старые главы unix использовали для обсуждения достоинств Consistency, Simplicity и Completeness. Консенсус в том, что Simplicity лучше всего, даже если он не является полным или последовательным. Для достижения полноты ваше оригинальное решение использует сложность. Это ловушка! (спасибо admiral ackbar)

например. так работает мой/мой клиент, поэтому он должен работать таким образом

Программное обеспечение дешевле/проще писать, когда мы ищем способы достижения простоты. Иногда это означает изменение организации в соответствии с ограничениями программного обеспечения.

Я могу представить себе реплику к вышесказанному, что государства

Вариант 1 даст вам скидку 10% на Вариант 2. Вы только статические цены !.

Это может быть смоделировано по схеме выше, где общая цена равна цене Варианта 1. +9 (цены Варианта 2). В этом случае мы только что взяли понятие Variation и сделали его данными вместо поведения. Гораздо проще. Это более гибко. Я имею в виду, что вы можете сделать сложное 3D объемное исчисление по ценам и просто привести результат в свою схему продукта. Есть больше проблем для рассмотрения ...

Я не хочу делать эту конфигурацию вручную!

Напишите себе команду управления Django, которая импортирует из электронной таблицы.

Что делать, если цены или отношения между Options изменены?

Большинство продуктов/цена схемы включают в себя понятие _spec как Option_spec, что позволяет захватывать момент времени условия покупки. _spec записей подключены к Purchase в то время, когда вещи покупаются. Это позволяет изменять Option и OptionSet, не меняя всех подключенных прошлых покупок.

и список продолжается ...

Дело в том, что все проблемы, вы можете мечтать иметь простые решения, если вы умны и открытыми.

+0

Спасибо за очень подробный ответ. Я буду смотреть на каждую «Ловушку», о которой вы указали. –