October 21, 2024
Chicago 12, Melborne City, USA
python

Issue Displaying All Colors of a Product Variant in Django Template


I’m working on a Django application where I have a Product model with a many-to-many relationship with a Color model. I want to display all colors associated with a product variant on its detail page. However, when I click on a specific color (e.g., white), the page only shows that color instead of all available colors for the product variant.

Here’s the relevant code:

Models:

class Color(models.Model):
    code = models.CharField(max_length=7)  # Hex color code
    image = models.ImageField(upload_to='colors/')  # Image field for color representation
    product_varients = models.ManyToManyField('Product', related_name="color_variants", blank=True)

class Product(models.Model):
    pid = ShortUUIDField(length=10, max_length=100, prefix="prd", alphabet="abcdef")
    user = models.ForeignKey(CustomUser , on_delete=models.SET_NULL, null=True)
    category = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True, related_name="category")
    color = models.ManyToManyField(Color, blank=True)

View Function:

def product_varient_detail_view(request, pid):  
    try:  
        product_variant = Product.objects.get(pid=pid)  
    except Product.DoesNotExist:  
        return render(request, "core/error_page.html")  
    
    wishlist = wishlist_model.objects.filter(user=request.user) if request.user.is_authenticated else None  
    sub_category = SubCategory.objects.all()  
    categories = Category.objects.prefetch_related('subcategories').order_by('?')[:4]  
    nav_category = Category.objects.filter(special_category=True).prefetch_related('subcategories').order_by('?')[:4]  
    
    # Initialize variables  
    colors = product_variant.color_variants.all()  # Get the colors of the product variant
    linked_colors = set()  # Use a set to avoid duplicates
    
    # Get linked colors  
    for color in colors:  
        for linked_product in color.product_varients.exclude(id=product_variant.id):  # Exclude current product
            linked_colors.update(linked_product.color_variants.all())  # Update the set with linked product colors
    
    # Convert linked_colors back to a list for the template
    linked_colors = list(linked_colors)
    
    sizes = product_variant.size.filter(product=product_variant)  
    p_image = product_variant.p_images.filter(product=product_variant)  
    
    # Getting review  
    reviews = ProductReview.objects.filter(product=product_variant)  
    review_count = reviews.count()  
    average_rating = ProductReview.objects.filter(product=product_variant).aggregate(rating=Avg('rating'))  
    
    # Product Review Form  
    review_form = ProductReviewForm()  
    
    if request.GET.get('color'):  
        color_id = request.GET.get('color')  
        color = Color.objects.get(coid=color_id)  
        product_varient = color.product_varients.first()  
        if product_varient:  
            return redirect('core:product_varient_detail', pid=product_varient.pid)  
    
    try:  
        product_p = Product.objects.get(pid=pid)  
        context1 = {'product_p': product_p}  
        if request.GET.get('size'):  
            size_name = request.GET.get('size')  
            size_object = Size.objects.get(name=size_name)  
            price = product_variant.get_product_price_by_size(size_object)  
            context1['selected_size'] = size_name  
            context1['updated_price'] = price  
    
    except Exception as e:  
        print(e)  
        return render(request, "core/error_page.html")  
    
    main_product_color = product_variant.main_product_color  
    
    context = {  
        "p": product_variant,  
        "w": wishlist,  
        "p_image": p_image,  
        "sub_category": sub_category,  
        "categories": categories,  
        "nav_category": nav_category,  
        'colors': colors,  
        'linked_colors': linked_colors,  
        'sizes': sizes,  
        'reviews': reviews,  
        'review_count': review_count,  
        'average_rating': average_rating,  
        'review_form': review_form,  
        'main_product_color': main_product_color,  
    }  
    
    context.update(context1)  
    return render(request, "core/product_varient_detail.html", context)

Template Code:

{% if colors %}
    {% for c in colors %}
        <div class="color__radio">
            <input type="radio" id="color_{{ c.id }}" name="color" 
                   data-image-url="{{ c.image.url }}" 
                   class="color-input" 
                   data-url="{% url 'core:product_varient_detail' c.product_varients.first.pid %}?color={{ c.coid }}">
            <label class="color__radio-label" 
                   for="color_{{ c.id }}" 
                   style="background-color: {{ c.code }};"></label>
        </div>
    {% endfor %}
{% endif %}

{% if linked_colors %}
    <h3>Linked Product Colors</h3>
    {% for c in linked_colors %}
        <div class="color__radio">
            <input type="radio" id="linked_color_{{ c.id }}" name="linked_color" 
                   data-image-url="{{ c.image.url }}" 
                   class="color-input" 
                   data-url="{% url 'core:product_varient_detail' c.product_varients.first.pid %}?color={{ c.coid }}">
            <label class="color__radio-label" 
                   for="linked_color_{{ c.id }}" 
                   style="background-color: {{ c.code }};"></label>
        </div>
    {% endfor %}
{% endif %}

The issue I'm facing is that when I click on a specific color, the page only shows that color instead of all available colors for the product variant. How can I modify my code to ensure that all colors are displayed on the product variant detail page, regardless of which color I click on?



You need to sign in to view this answers

Leave feedback about this

  • Quality
  • Price
  • Service

PROS

+
Add Field

CONS

+
Add Field
Choose Image
Choose Video