只显示一次对象并计算它

时间:2014-09-29 07:32:04

标签: django

在搜索了很长时间后没有得到答案我会在这里尝试。

我正在研究django。我的项目是一个mailling系统,每次收件人打开邮件时我都知道打开邮件的邮件是什么以及何时打开邮件。 这是我显示统计数据的表格。它向我显示了每个收件人和日期时间,但我的问题是我想要查看每个收件人一次,然后显示它被打开的次数。

        <tbody>
          {% for stat_mail in stat_mail %}
            {% ifchanged stat_mail.recipient %}
              <tr>
                  <td>{{ stat_mail.recipient }}</td>
                  <td>{{ stat_mail.datetime }}</td>
                  <td>{{ stat_mail.recipient_set.all|length }}</td>
              </tr>
            {% endifchanged %}
          {% endfor %}
        </tbody>

例如: 测试1在下午5点和晚上8点打开邮件,因此表格应显示

测试1 / 5PM,8PM / 2

收件人的姓名,操作日期和操作次数。

抱歉英语不好,但我是法语:)

希望有人可以帮助我,如果你有其他问题或需要更多代码,请问。

非常感谢!

编辑:我的models.py

class Recipient(models.Model):
name = models.CharField(max_length=255, verbose_name= ('Nom'), null=True, blank=True)
first_name = models.CharField(max_length=255, verbose_name= ('Prénom'), null=True, blank=True)
mail = models.EmailField(verbose_name= ('Adresse du destinataire'))
def __unicode__(self):
    return u'%s %s' % (self.name, self.first_name)

class Tag(models.Model):
name = models.CharField(max_length=255, blank=False)
recipients = models.ManyToManyField(Recipient, verbose_name='Destinataires', null=False, blank=False, related_name="tags")
def __unicode__(self):
    return self.name

class Mail(models.Model):
subject = models.CharField(max_length=255, verbose_name= ('Sujet'), blank=False, null=False)
content = HTMLField(verbose_name= ('Contenu'), blank=False, null=False, default=' ')
tags = models.ManyToManyField(Tag, verbose_name= ('Destinataires'), null=True, blank=True, related_name='mails')
recipients = models.ManyToManyField(Recipient, verbose_name='Destinataires', null=True, blank=True, related_name='mails')
date_create = models.DateTimeField(verbose_name= ('Date de création'), default=datetime.now, blank=False, editable = False)
writer = models.ForeignKey(Intervenant, verbose_name= ('Personne écrivant la compagne'), null=True, blank=True) 
holding = models.ForeignKey(Holding, verbose_name= ('Organisation'),related_name= ('Questionnaire_mail'), null=False, blank=False, default=1, editable = False)
sended = models.BooleanField(verbose_name = ('Compagne envoyée ?'), default=False, editable=False)
opened = models.IntegerField(verbose_name=("Nombre totale d'ouverture"), default=0, editable=False)
email = models.EmailField(verbose_name='Destinataire de Test', blank=True, null=True)

date_create = models.DateTimeField(verbose_name= ('Date de création'), default=datetime.now, blank=False, editable = False)
date_sent = models.DateTimeField(verbose_name= ('Date de création'), blank=True, null=True, editable = False)

def __unicode__(self):
    return self.subject

class Mail_Stats(models.Model):
mail = models.ForeignKey(Mail, verbose_name= ('Compagne'), related_name='mails_stats')
recipient = models.ForeignKey(Recipient, verbose_name= ('Destinataires'), null=True, blank=True, related_name='mails_stats')
datetime = models.DateTimeField(verbose_name= ('Date et Heure'), auto_now_add=True)

1 个答案:

答案 0 :(得分:0)

您应该在视图中准备数据,然后将其传递给模板。像这样(未经测试):

from django.shortcuts import render

from .models import Mail_Stats

def stats_view(request):
    recipient_list = [] # this will be put in the template context

    current_recipient = None
    cnt_read = 0
    read_datetime_list = []

    for stat in Mail_Stats.objects.all().order_by('mail', 'recipient'):
        if stat.recipient != current_recipient:
            if cnt_read > 0:
                recipient_list.append({
                    'recipient': current_recipient,
                    'read_datetime_list': read_datetime_list,
                    'cnt_read': cnt_read
                })
            current_recipient = stat.recipient
            cnt_read = 0
            read_datetime_list = []
        cnt_read += 1
        read_datetime_list.append(stat.datetime)

    # add last recipient to the list, if not None
    if current_recipient is not None:
        recipient_list.append({
            'recipient': current_recipient,
            'read_datetime_list': read_datetime_list,
            'cnt_read': cnt_read
        })

    render(request, 'mail_stats.html', { 'recipient_list': recipient_list })

然后在你的模板中你可以做这样的事情:

<tbody>
    {% for r in recipient_list %}
        <tr>
            <td>{{ r.recipient }}</td>
            <td>
                <ul>
                {% for dt in r.read_datetime_list %}
                    <li>{{ dt }}</li>
                {% endfor %}
                </ul>
            </td>
            <td>{{ r.cnt_read }}</td>
        </tr>
    {% endfor %}
</tbody>

重要的是:不要在模板中做复杂的事情,只保留它们用于演示目的。移动视图(或模型或实用程序模块)中的所有逻辑,您可以利用Python的所有功能。