Django: проверка, существует ли объект в queryset (если еще)


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

Модель 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 в модели Varaition будет использоваться тележкой.

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

Модель Cart 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

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

ЧТО Я ПРОБОВАЛ:

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

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

1 6

1 ответ:

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

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

  • секция - группа вариантов
  • опцион - Цена
  • вариация - попытка моделирования вариантов, влияющих на другие варианты

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

Ловушка 1

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

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

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

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

Ловушка 2

Позволяя тому, как вы хотите, чтобы он работал, не позволяйте ему работать вообще

Теперь, прежде чем вы начнете залп "это не может работать для меня, я снежинка!"(был здесь а долгое время). Часто мы обнаруживаем, что способ, которым мы хотим, чтобы что-то работало, стоит на пути его работы.

Старые главы Unix, используемая для дискуссии по существу непротиворечивости, простоты и полноты. Все согласны с тем, что простота лучше всего, даже если она не является полной или последовательной. Ваше оригинальное решение выглядит так, чтобы использовать сложность для достижения полноты. это ловушка! (спасибо адмиралу Акбару)

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

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

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

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

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

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

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

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

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

И этот список можно продолжать... Суть здесь в том, что все проблемы, о которых вы можете мечтать, имеют простые решения, если вы умны и открыты.