I found that for each selection in the basket, more than 26 queries are called. Does this db schema require more normalization or is it good enough for this simple project?
I will bite because I believe the solution to this is software development. The problem here is not normalization, and it is not Django. How did you decide to organize the problem. I assume that you have fallen into several traps, which I will tell about when we go. First, give some definitions right here, starting with your own ...
- Section - option group
- Option - price
- Variation - an attempt to simulate parameters that affect other parameters.
Now do we have this problem? Some of my Option
options can be used with other Option
options and influence the price! Chaos! We need Variation
provide meta rules for their interaction. More inquiries! More logic! May be,...
Trap 1
Providing a way to display information on the screen of your data model
I guess here, but using the words Section
and Option
makes me feel like you're organizing a screen, not a database. Most often, companies have models that look like this:
Product
- We are selling something ( name
, base_price
, options
, option_sets
)OptionSet
- Groups of options that come together as a package! Think about saving! ( name
, group
, options
, price
, optionset_exclusions
, option_exclusions
)Option
- parameters a la carte ( name
, group
, price
)Purchase
- Who wants to buy ( Product
, options
, optionsets
)
Now you can say: "How about my sections!" Sections can be as easy as hanging up a piece of metadata with OptionSet
and Option
called group
with type CharField
. When rendering in a template, you can group parameters / options together group
. You can use exclusions
so that people cannot select conflicting Option
and optionsets
for Product
. Now all this shebang can be folded on the page with just three requests (if used correctly, prefetch_related
), and the selected options
/ optionsets
can simply be added together to get a deterministic price.
Trap 2
Denying how you want it to work prevents it from working at all
Now, before you launch the volley, "This can't work for me, I'm a snowflake!" (here it was a long time ago). Often we find that the way we want to work something prevents it from working.
Older unix chapters used to discuss the virtues of Consistency, Simplicity, and Completeness. The consensus is that Simplicity is best, even if it is not complete or consistent. To achieve completeness, your original solution uses complexity. It is a trap! (Thanks Admiral Akbar)
eg. this is how my / my client business works, so it should work that way.
Software is cheaper / easier to write when we look for ways to achieve simplicity. Sometimes this means changing the organization to meet software limitations.
I can present the retort to the foregoing, which says
Option 1 will give you a 10% discount on option 2. You only have static prices!
This can be modeled in the diagram above, where the total price is equal to Option 1 Price +.9 (Option 2 prices). In this case, we just took the concept of Variation
and made it data instead of behavior. Much easier. It is more flexible. I mean, you can make a complex 3D volume calculation at prices and just bring the result into your product schema. There are more problems to consider ...
I do not want to do this configuration manually!
Write yourself a Django management command that imports from a spreadsheet.
What if prices or the relationship between options
change?
In the product / price scheme itself, there is the concept of _spec
as Option_spec
, which allows you to fix the Point In Time purchase conditions. _spec
entries _spec
connected to the Purchase
at the time of purchase. This allows you to change Option
and OptionSet
without changing all connected past purchases.
and the list goes on ...
The fact is that all the problems you can dream of have simple solutions if you are smart and open-minded.