在Django中循环for另一个for循环中的循环

时间:2018-05-29 18:47:11

标签: django templates

首先请看我的代码:

我的模特:

class review_product_individual(models.Model):

 product_id  = models.CharField(max_length=30)
 product_star = models.CharField(max_length=30)
 product_review_message = models.CharField(max_length=255,blank=True)
 product_reviewed_by = models.CharField(max_length=30)
 product_review_date = models.DateTimeField(auto_now_add=True, blank=True)

观点:

product_review = review_product_individual.objects.filter(product_id = productID).order_by('-product_review_date') 

此处product_star将包含1到5的评级并存储为char。现在我要做的是这将在for循环中访问Django模板中的每个product_review对象,在for循环中我将迭代product_review.product_star times.please在这里看到模板代码:`

                {% for product_review in product_review %}
            <li>
                <div class="review-heading">
                    <h5 class="name">{{product_review.product_reviewed_by}}</h5>
                    <p class="date">27 DEC 2018, 8:0 PM</p>
                    <div class="review-rating">
                    {% for i in product_review.product_star %}

                        <i class="fa fa-star"></i>

                    {% endfor %}


                        <i class="fa fa-star-o empty"></i>
                    </div>
                </div>
                <div class="review-body">
                    <p>{{product_review.product_review_message}}</p>
                </div>
            </li>

            {% endfor %}

但只有一颗星打印为{{product_review.product_star}} = 3的值 我想要三颗星。我无法在视图中执行,因为product_review包含许多对象。那我怎么能这样做呢?

1 个答案:

答案 0 :(得分:1)

我觉得将评分存储为CharField(所以是一个字符串),而不是使用IntegerFieldIntegerField,我觉得很奇怪,你可以计算总和,平均值,以数字顺序排列元素(不按字典顺序排列)等。

所以我建议你改用IntegerField

class ReviewProductIndividual(models.Model):
    product_id  = models.CharField(max_length=30)
    product_star = models.IntegerField()
    product_review_message = models.CharField(max_length=255,blank=True)
    product_reviewed_by = models.CharField(max_length=30)
    product_review_date = models.DateTimeField(auto_now_add=True, blank=True)

所以现在我们可以存储数字评级的评级。

接下来您的模板问题是您迭代字符串。如果迭代字符串,则迭代其字符。这意味着如果您存储'5',它将迭代一次:迭代器将获得字符5。但你想要迭代五次。

您可以做的是例如定义{% range ... %}标记,例如this snippet does。我们可以在 __init__.py 中创建一个包(带有appname/templatetags/range.py文件)(因此添加一个空文件 appname/templatetags/__init__.py ) :

from django.template import Library, Node, TemplateSyntaxError

register = Library()

class RangeNode(Node):

    def __init__(self, num, context_name):
        self.num = Variable(num)
        self.context_name = context_name

    def render(self, context):
        context[self.context_name] = range(int(self.num.resolve(context)))
        return ""

@register.tag
def num_range(parser, token):
    """
    Takes a number and iterates and returns a range (list) that can be 
    iterated through in templates

    Syntax:
    {% num_range 5 as some_range %}

    {% for i in some_range %}
      {{ i }}: Something I want to repeat\n
    {% endfor %}

    Produces:
    0: Something I want to repeat 
    1: Something I want to repeat 
    2: Something I want to repeat 
    3: Something I want to repeat 
    4: Something I want to repeat
    """
    try:
        fnctn, num, trash, context_name = token.split_contents()
    except ValueError:
        raise TemplateSyntaxError, "%s takes the syntax %s number_to_iterate\
            as context_variable" % (fnctn, fnctn)
    if not trash == 'as':
        raise TemplateSyntaxError, "%s takes the syntax %s number_to_iterate\
            as context_variable" % (fnctn, fnctn)
    return RangeNode(num, context_name)

请注意,这是一个略有修改的版本(使用代码段中的注释进行更新)。

现在我们可以使用此{% num_range ... %}标记:

{% for product_review in product_review %}
<li>
    <div class="review-heading">
        <h5 class="name">{{product_review.product_reviewed_by}}</h5>
        <p class="date">27 DEC 2018, 8:0 PM</p>
        <div class="review-rating">
        {% num_range product_review.product_star as star_range %}
        {% for _ in star_range %}

            <i class="fa fa-star"></i>

        {% endfor %}


            <i class="fa fa-star-o empty"></i>
        </div>
    </div>
    <div class="review-body">
        <p>{{product_review.product_review_message}}</p>
    </div>
</li>
{% endfor %}