无法弄清楚在django中使用prefetch_related

时间:2016-08-21 05:28:58

标签: python django django-models query-optimization django-orm

有一种情况我希望显示用户的总购买量。我在userprofiles模型中使用了@property。幸运的是,它正如我预期的那样工作。但是我想使用prefetch_related来优化django查询,因为从order_history计算用户的总购买量,order_history与OrderMenu具有ManyToMany Relation。

我是怎么做的?

<table>
    <thead>
    <tr>
        <th rowspan="2">Name</th>
        <th colspan="2"><?php echo date('Y', strtotime('-2 year')); ?></th>
        <th colspan="2"><?php echo date('Y', strtotime('-1 year')); ?></th>
        <th colspan="2"><?php echo date('Y', strtotime('0 year')); ?></th>
    </tr>
    <tr>
        <th>scheduled</th>
        <th>actual</th>
        <th>scheduled</th>
        <th>actual</th>
        <th>scheduled</th>
        <th>actual</th>
    </tr>
    </thead>
    <tbody>
    <?php
    foreach ($deptlist as $row) {
        ?>
        <tr>
            <td><?php echo $row->name; ?></td>
            <?php
            $status_array = explode(',', $row->status_string);
            $date_array = explode(',', $row->date_string);
            for ($year = date('Y', strtotime('-2 year')); $year <= date('Y'); $year++) {
                $scheduledValue = false;
                $actualValue = false;
                foreach ($date_array as $dateKey => $yearRow) {
                    if (strpos($yearRow, (string)$year) === 0) {
                        if ($status_array[$dateKey] == 'scheduled') {
                            $scheduledValue = $yearRow;
                        } elseif ($status_array[$dateKey] == 'actual') {
                            $actualValue = $yearRow;
                        }
                    }
                }
                if ($scheduledValue) {
                    echo "<td>{$scheduledValue}</td>";
                } else {
                    echo '<td> - </td>';

                }
                if ($actualValue) {
                    echo "<td>{$actualValue}</td>";
                } else {
                    echo '<td> - </td>';

                }
            }
            ?>
        </tr>
    <?php } ?>

    </tbody>
</table>
  

在此解决方案中,不是

     

userprofile = UserProfile.objects.get(slug = self.slug)user_order =   userprofile.order_history.all()

     

相当于

     

user_order = UserProfile.objects.prefetch_related( 'order_history')。得到(蛞蝓= self.slug)

我对prefetch_related非常困惑。有人可以用简单的语言来启发我吗?对不起,我是非英语母语人士。

1 个答案:

答案 0 :(得分:2)

两者之间的区别是

如果是

userprofile = UserProfile.objects.get(slug=self.slug) #hits数据库

此查询根据数据库

中的条件获取userprofile的对象

user_order = userprofile.order_history.all() #hits数据库再次

此查询使用userprofile对象再次访问数据库获取user_order查询集。

即。 userprofile命中数据库以及user_order

但是在这种情况下

user_order=UserProfile.objects.prefetch_related('order_history').get(slug=self.slug)

user_order queryset set不仅返回用户个人资料对象,还返回&#39; order_history&#39;在一次命中数据库时与UserProfile对象相关的queryset。现在当你访问&#39; order_history&#39;使用user_order对象的querset不会命中数据库,但会获得&#39; order_history&#39;的查询集。来自预先设定的&#39; user_order&#39;的QuerySet缓存。更多关于它here