Search code examples
pythonhtmldjangomodel

Django Model Error : Code is not getting renderd


So, I having a database in which there is html code which i wanna render i show you the model first

model.py

class Badge(models.Model):
    
    name = models.CharField(max_length=255)
    code = models.CharField(max_length=700, default='<h5><span class="badge bg-primary ms-2">New</span></h5>')
    code_price = models.CharField(max_length=700, default='<s>{{product.price | safe}}</s><strong class="ms-2 text-danger">{{product.get_price_with_discount() | safe}}</strong>')
    # product = models.ForeignKey(Product, on_delete=models.CASCADE, related_name='badges')
    
    def __str__(self):
        return self.name

class Product(models.Model):
    """A product."""

    name = models.CharField(max_length=255)
    price = models.DecimalField(max_digits=10, decimal_places=2)
    image = models.ImageField(upload_to='static/img/' , default='/static/img/404.png')
    category = models.ForeignKey(Category, on_delete=models.CASCADE)
    type = models.ForeignKey(Badge, on_delete=models.CASCADE, related_name= "products")
    
    def get_price_with_discount(self):
        discount = (self.price) * (10 / 100)
        return self.price - discount

now in Django it cant find the product.price since product is defined later or u can say it renders it but as a string i send the html page code now

services.html

    <section>
        <div class="text-center container py-5">
            <h4 class="mt-4 mb-5"><strong>Bestsellers</strong></h4>

            <div class="row">
                {% for product in products %}

                <div class="col-lg-4 col-md-12 mb-4">
                    <div class="card">
                        <div class="bg-image hover-zoom ripple ripple-surface ripple-surface-light"
                            data-mdb-ripple-color="light">
                            <img src="{{product.image.url}}" class="w-100" style="height: 500px;" />
                            <a href="#!">
                                <div class="mask">
                                    <div class="d-flex justify-content-start align-items-end h-100">
                                        {% comment %} <h5><span class="badge bg-primary ms-2">New</span></h5> {%endcomment %}
                                        {{product.type.code|safe}}
                                    </div>
                                </div>
                                <div class="hover-overlay">
                                    <div class="mask" style="background-color: rgba(251, 251, 251, 0.15);"></div>
                                </div>
                            </a>
                        </div>

                        <div class="card-body">
                            <a href="" class="text-reset">
                                <h5 class="card-title mb-3">{{ product.name}}</h5>
                            </a>
                            <a href="" class="text-reset">
                                <p>{{ product.category.name}}</p>
                            </a>
                            <h6 class="mb-3">${{ product.type.code_price | safe }}</h6>
                        </div>

                    </div>
                </div>
            {% endfor %}

        </div>
    </section>

I want to it something like this Want

and i got something like this Got


Solution

  • Well you don't store the rendered data in the string, you simply store the code in the string.

    But I would not do that anyway: you can just render it from a string, so:

    from django.template import Context, Template
    
    
    class Badge(models.Model):
        # …
        
        code_price = models.CharField(
            max_length=700,
            default='<s>{{product.price|safe}}</s><strong class="ms-2 text-danger">{{product.get_price_with_discount|safe}}</strong>',
        )
    
    
    class Product(models.Model):
        # …
        
        def get_price_with_discount(self):
            discount = self.price * (10 / 100)
            return self.price - discount
    
        def render_code_price(self):
            template = Template(self.type.code_price)
            return template.render(Context({'product': self}))

    Then in the template, you can use:

    {{ product.render_code_price }}
    

    and it will use the code_price of the related Badge to do this.

    You also can't use parenthesis in Django's template language so {{ product.get_price_with_discount }}, not {{ product.get_price_wit_discount() }}. You will likely have to alter in in the existing badges in the database.