14. Displaying product size based on color selected
To dynamically display available product sizes based on the selected color, we will implement a solution that appends the color identifier to the product URL. This approach ensures that each color variant is accessed through a unique URL.
We will integrate the id_color
variable as a parameter within the view_product
function, initializing it with a default value of None
. It is important to note that the parameters passed to the functions are derived from the URL components.
def view_product(request, product_id, id_color = None) :
Next, we will define a new path in the urls.py
file to accommodate the URL that includes the color ID parameter. This will ensure the routing system correctly handles URLs containing the color identifier.
path('product/<int:product_id>', view_product, name="view_product"),
path('product/<int:product_id>/<int:id_color>', view_product, name="view_product"),
To simplify the logic, we will modify the view_product
function by initially setting the has_stock
condition to False
and initializing the sizes
and colors
sets as empty. This approach will allow us to eliminate the else
statements at the end of the function, saving lines.
def view_product(request, product_id, id_color = None) :
has_stock = False
sizes = {}
colors = {} #? needs to be declared
To display the available sizes for each product based on the selected color, we will enhance the logic within the view_product
function. Specifically, we will add a condition inside the stock check to filter the products by the selected color. If a color is specified, the function will query the database using the color__id
attribute, which retrieves the color ID created automatically from the Color class. This filtered query will then populate a set with all available sizes for the specified product color.
if len(item_stock) > 0 :
has_stock = True #? necessary in order to do a if on the html. if the product is out of stock, will show "Out of Stock"
colors = {item.color for item in item_stock} #? gets the colors of all products, uses sets '{}' to avoid duplicate colors
if id_color :
item_stock = ItemStock.objects.filter(product = product, quantity__gt = 0, color__id = id_color) #? gets the color id attribute from the Color class (that is automatically created)
sizes = {item.size for item in item_stock} #? gets the sizes of all products
Adding the sizes
variable to the context dictionary:
context = {'product': product, 'item_stock': item_stock, "has_stock" : has_stock, "colors" : colors, "sizes" : sizes}
Within the view_product.html
template, we will remove the display of color names and make the color icons clickable. These clickable icons will direct the user to the URLs of the specific color IDs, which will in turn display the available sizes for that color.
<a href = "{% url 'view_product' product.id color.id %}"> <!--passing the url of 'view_product' determined in the name parameter of the urls.py, followed by the product.id and the color.id -->
<i class="fa-solid fa-circle" style="color: {{ color.code }}"></i> <!--False positive, html doesnt recognize the django format but it is correct -->
</a>
{% endfor %}
{% if sizes %}
<p>Select the size:</p>
{% for size in sizes %}
<button>{{ size }}</button>
{% endfor %}
{% endif %}

Lastly, we will just display which color is being selected
Initializing a new variable selected_color_name
def view_product(request, product_id, id_color = None) :
has_stock = False
sizes = {}
colors = {} #? needs to be declared
selected_color_name = None
Obtaining the selected color name using its id
if id_color :
color = Color.objects.get(id = id_color) #? gets the color object from the Color class
selected_color_name = color.name
Adding selected_color_name
to the context dictionary
context = {'product': product, 'item_stock': item_stock, "has_stock" : has_stock, "colors" : colors, "sizes" : sizes, "selected_color_name" : selected_color_name}
Displaying it before the color icon for loop
{% if selected_color_name %}
Color: {{ selected_color_name }}
{% endif %}
{% for color in colors %}

Last updated