6

PROBLEM: Problem mam jest coraz cenę opcji w Selection modelu. Dzieje się tak dlatego, że w zależności od tego, które inne opcje będą znajdować się w tym samym koszyku, do wygenerowania sumy zostaną użyte różne ceny. Potrzebuję pomocy w zestawie zapytań, który dostarczy mi cenę opcji Opcja, jeśli opcja ma efektora efektorów, która sama znajduje się w tym samym wózku, z której korzysta, w przeciwnym razie użyje tylko zestawu pól opcji.Django: Sprawdzanie, czy obiekt istnieje w queryset (IF ELSE)

TempName App Model składa się z:

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 

Istnieje wiele Sekcje na jednej stronie. Każdy może zawierać wiele opcji, które później będzie można wybrać przez użytkownika. Wybrana opcja Opcja trafi do koszyka, który zostanie użyty do wygenerowania całkowitej ceny.

ciągu Variation modelu, opcja pole po prostu mówi mi, który Opcja Variation należy. Jednak w koszyku będzie używane pole modelu w modelu Varaition.

Użytkownik będzie mógł wybrać dowolną liczbę Opcje, jednak w zależności od Opcje wybranego użytkownika, inne opcje mogą wyświetlać zmienności cenę gdzie wcześniej został wybrany effector_option.

Koszyk App Model składa się z:

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 

Wózek może zawierać wiele Opcje które wybrał użytkownik. Każda z nich będzie miała właściwość ceny, która może być użyta do pokazania użytkownikowi ceny tego indywidualnego wyboru w zależności od tego, która inna opcja jest również w tym samym wózku.

co to próbowałem:

Get wszystkich odmian opcji. Następnie przeprowadź pętlę przez każdą zmianę i sprawdź, czy opcja Variation.effector_ jest zawarta w tym samym koszyku Cart. Jeśli tak, wyświetl tę cenę, w przeciwnym razie wyświetl cenę w wariancie, w której Variation.effector_option ma wartość null/not set.

Stwierdziłem, że ponad 26 zapytań było wywoływanych dla każdego Selection w koszyku. Czy ten schemat bazy danych wymaga więcej normalizacji lub czy jest wystarczająco dobry dla tego prostego projektu?

+0

Przeczytaj o tym, jak zapytać (operatorzy zestawów zapytań), a nie zapętlić. – philipxy

+0

@philipxy Tak, zrobiłem to, jednak mam problem z zapytaniem o zestaw zapytań, a następnie zapytanie o wynikowy zestaw zapytań. Znowu przeczytam tę część dokumentów, może coś przeoczyłem. –

+1

Google 'stackoverflow.com django wynik zapytania innego zapytania'. – philipxy

Odpowiedz

3

Stwierdziłem, że do każdego wyboru w koszyku zgłoszono ponad 26 zapytań. Czy ten schemat bazy danych wymaga więcej normalizacji lub czy jest wystarczająco dobry dla tego prostego projektu?

Ugryzie, ponieważ wierzę, że rozwiązaniem tego jest inżynieria oprogramowania. Problemem tutaj nie jest normalizacja, ani Django. To jest sposób, w jaki zdecydowałeś się zorganizować problem. Domyślam się, że wpadłeś w kilka pułapek, które omówię w trakcie naszej podróży. Najpierw przejdźmy niektóre definicje prosto tutaj wychodząc z własnego ...

  • Sekcja - grupa opcji
  • opcja - Cenę
  • Variation - próba modelowania opcje Wpływ na inne opcje

Teraz mamy ten problem, prawda? Niektóre z moich wyborów Option mogą być używane z innymi wyborami Option i mają wpływ na cenę! Chaos! Potrzebujemy Variation, aby zapewnić reguły meta dla ich interakcji. Więcej pytań! Więcej logiki! Może ...

Pułapka 1

Letting drogę rzeczy wyglądają na ekranie jazdy model danych

zgaduję tutaj ale użycie słowa Section i Option marki czuję, że organizujesz ekran, a nie bazę danych. Częściej firmy mają modele, które wygląda następująco ...

  • Product - Coś sprzedajemy (name, base_price, options, option_sets)
  • OptionSet - grup opcji, które wchodzą ze sobą w ramach pakietu! Pomyśl o oszczędności (name, group, options, price, optionset_exclusions, option_exclusions)
  • Option - a la carte opcje (name, group, price)
  • Purchase - Co ktoś chce kupić (product, options , optionsets)

Teraz możesz mówić "A co z moimi sekcjami!" Sekcje mogą być czymś tak łatwym, jak powieszenie fragmentu metadanych off OptionSet i Option o nazwie group o typie CharField. Podczas renderowania w twoim szablonie możesz grupować opcje/zestawy opcji razem przez group. Możesz użyć exclusions, aby uniemożliwić innym użytkownikom wybór sprzecznych Option i OptionSets dla Product.Teraz ten cały shebang może zostać umieszczony na stronie z zaledwie trzema zapytaniami (z właściwym użyciem prefetch_related) i wybrany Options/OptionSets może być po prostu dodany, aby uzyskać deterministyczną cenę.

Pułapka 2

Letting sposób chcesz go do pracy zapobiec jego działa w ogóle

Teraz przed uruchomić salwy „To nie może pracować dla mnie, Jestem płatkiem śniegu! "(Byłem tu przez długi czas). Często okazuje się, że sposób, w jaki chcemy, aby coś działało, stoi na drodze do działania.

Stare głowy unix używane do debaty na temat zalet konsystencji, prostoty i kompletności. Konsensus jest taki, że prostota jest najlepsza, nawet jeśli nie jest pełna ani spójna. Twoje oryginalne rozwiązanie wygląda na skomplikowane, aby osiągnąć Kompletność. To pułapka! (dzięki admiral ackbar)

np. w ten sposób działa mój/mój klient, więc musi działać w ten sposób.

Oprogramowanie jest tańsze/łatwiejsze do napisania, gdy szukamy sposobów na osiągnięcie prostoty. Czasami oznacza to zmianę organizacji w celu dostosowania się do ograniczeń oprogramowania.

mogę sobie wyobrazić ripostę na powyższym stwierdza

Opcja 1 da ci zniżkę 10% na Opcji 2. Trzeba tylko ceny statycznych !.

Można to modelować w schemacie powyżej, gdzie łączna cena jest równa cenie 1 opcji .9 (ceny opcji 2). W tym przypadku właśnie przyjęliśmy pojęcie Variation i stworzyliśmy dane zamiast zachowania. Znacznie prostsze. Jest bardziej elastyczny. Chodzi mi o to, że możesz wykonać skomplikowany kalkulator objętościowy w 3D dla cen i po prostu przekształcić wynik w swój schemat produktu. Jest jeszcze więcej problemów do rozważenia ...

Nie chcę wykonywać całej tej konfiguracji ręcznie!

Napisz sobie polecenie zarządzania Django, które importuje z arkusza kalkulacyjnego.

Co się stanie, jeśli zmianie ulegną ceny lub relacje między Options?

Większość produktów/Cena schematu na miejscu to pojęcie _spec jak Option_spec który pozwala uchwycić punkt w czasie warunków zakupu. _spec Dokumenty są podłączone do Purchase w momencie zakupu rzeczy. Pozwala to na zmianę Option i OptionSet bez zmiany wszystkich połączonych wcześniejszych zakupów.

a lista jest długa ...

Chodzi o to, że wszystkie problemy mogą marzysz mają proste rozwiązania, jeśli jesteś mądry i otwarci.

+0

Dziękuję za bardzo wyczerpującą odpowiedź. Będę się przyglądał każdemu "pułapce", którą wskazałeś. –