Django Queryset加载时间太长

时间:2019-01-23 13:09:23

标签: django python-3.x django-queryset

我刚刚将一个项目上传到我在数字海洋上的服务器。加载合作伙伴视图时,大约需要1分钟才能查询和过滤数据,然后显示d。有1,905,120个条目要过滤以显示约200,000个条目。如何优化流程?

views.py

class PartnershipView(LoginRequiredMixin, generic.ListView): 
model = Partnership
slug = ''
slug1 = ''
slug2 = ''

def get_context_data(self, **kwargs):
    context = super().get_context_data(**kwargs)
    slug = self.kwargs.get("slug")
    slug1 = self.kwargs.get("slug1")
    slug2 = self.kwargs.get("slug2")

    currentYear = datetime.datetime.now().year
    currentMonth = calendar.month_name[datetime.datetime.now().month]
    partnershipArms = PartnershipArm.objects.all()

    context['partnershipArms'] = partnershipArms


    partnershipArm = PartnershipArm.objects.get(slug = slug)

    if slug =='':
        partnerships = self.get_queryset().filter(partnershipArm = partnershipArm, year=currentYear, month = currentMonth )
    else:
        partnerships = self.get_queryset().filter(partnershipArm = partnershipArm, year=slug1, month = slug2 )
    members = Member.objects.all()

    context['currentYear'] = currentYear
    context['currentMonth'] = currentMonth
    context['partnershipArmName'] = partnershipArm.name
    context['partnershipArm'] = slug
    context['partnerships'] = partnerships
    context['members'] = members
    context['year'] = slug1
    context['month'] = slug2

    return context

partnership_list.html

<table id="datatable-buttons" class="table table-striped table-bordered">
    <thead>
        <tr>
            <th>Name</th>
            <th>contact</th>
            <th>Email</th>
            <th>Week 1</th>
            <th>Week 2</th>
            <th>Week 3</th>
            <th>Week 4</th>
            <th>Total</th>
        </tr>
    </thead>

    <tbody>
    {% for instance in partnerships %}
        <tr>
        {% for member in members %}
        {% if member.pk == instance.member_id %}
            <td>{{ member.title }} {{ member.fname }} {{ member.lname }}</td>
            <td>{{ member.contact }}</td>
            <td>{{ member.email }}</td>
        {% endif %}
        {% endfor%}
            <td><a href="{% url 'partnership-week1-update' partnershipArm instance.pk %}">{{instance.week1 }}</a></td>
            <td><a href="{% url 'partnership-week2-update' partnershipArm instance.pk %}">{{ instance.week2 }}</a></td>
            <td><a href="{% url 'partnership-week3-update' partnershipArm instance.pk %}">{{ instance.week3 }}</a></td>
            <td><a href="{% url 'partnership-week4-update' partnershipArm instance.pk %}">{{ instance.week4 }}</a></td>
            <td>{{ instance.total }}</td>
        </tr>
        {% endfor %}
    </tbody>
</table>

models.py

class PartnershipArm(models.Model):
name = models.CharField(max_length = 128)
slug = models.SlugField(unique = True, null=True, blank=True)
partnershipRecords = models.ManyToManyField(Member, through = 'Partnership') 

def __str__(self):
    return self.name

def get_absolute_url(self):
    return reverse('partnership-arms')

class Partnership(models.Model):

YEAR = []
for r in range((datetime.datetime.now().year), (datetime.datetime.now().year+10)):
    YEAR.append((r,r))
MONTHS = (
    ('January', 'January'),
    ('February', 'February'),
    ('March', 'March'),
    ('April', 'April'),
    ('May', 'May'),
    ('June', 'June'),
    ('July', 'July'),
    ('August', 'August'),
    ('September', 'September'),
    ('October', 'October'),
    ('November', 'November'),
    ('December', 'December'),
)
member = models.ForeignKey(Member, on_delete=models.CASCADE)
partnershipArm = models.ForeignKey(PartnershipArm, on_delete=models.CASCADE)
year = models.IntegerField( choices=YEAR, default=datetime.datetime.now().year)
month = models.CharField(max_length = 50, choices = MONTHS, null=True, blank=True)
week1 = models.DecimalField(max_digits=10, decimal_places=2, default = 0)
week2 = models.DecimalField(max_digits=10, decimal_places=2, default = 0)
week3 = models.DecimalField(max_digits=10, decimal_places=2, default = 0)
week4 = models.DecimalField(max_digits=10, decimal_places=2, default = 0)
total = models.DecimalField(max_digits=10, decimal_places=2, default = 0)
#keyChecker = models.CharField(max_length=250,unique=True, null=True, blank=True)

def __str__(self):
    return "{0}_{1}_{2}_{3}".format(self.member, self.partnershipArm, self.year, self.month)

def get_absolute_url(self):
    return reverse('partnership-arms')

1 个答案:

答案 0 :(得分:0)

您尚未发布模型,但是在db_index = Truefilter()中使用它们时,应确保在每个字段上都使用to set a database indexpartnershipArm), yearmonth

此外,当然也不建议在一页上显示所有数据,如果您的用例允许,请评估者使用某种pagination

在模板中,您正在遍历成员以找到适合您的伙伴关系实例的成员。如果您的成员数量较少,这可能已经比使用select_related('member')和直接访问instance.member更快的方法,但是我想说这很大程度上取决于数据库中成员/伙伴的数量。如果仍然要在单独的数据库查询中加载成员,那当然是将ID以键作为键的字典组织成员的更快方法,这样就不必遍历每一行。