如何避免每次在页面上调用get_absolute_url(django)?

时间:2016-04-01 05:13:46

标签: django django-models django-templates django-views

每个人都说在模板中使用get_absolute_url是一种很好的做法。但在我的情况下,它会在单个页面上对数据库产生大量相同的查询。 这是我必须开发的网址结构(我不能改变它,因为客户已经在网站上工作,如果我更改网址谷歌不会喜欢它) - mysite / category / subcategory / product_slug.html 这是url模式的代码:

from django.conf.urls import url
来自。导入视图

urlpatterns = [
    url(r'^(?P<parent_category_slug>[\w-]+)/(?P<category_slug>[\w-]+)/(?P<slug>[\w-]+)\.html$', views.ProductDetailView.as_view(), name='product_detail'),
    url(r'^(?P<parent_slug>[\w-]+)/(?P<slug>[\w-]+)$', views.ProductListView.as_view(), name='products_of_category'),
    url(r'^(?P<slug>\w+)$', views.SubCategoryListView.as_view(), name='sub_category'),
    url(r'^$', views.CatalogIndexListView.as_view(), name='index'),
]

以下是产品型号中的get_absolute_url代码:

def get_absolute_url(self):
    return reverse('product_detail', kwargs={'slug':self.slug, 'parent_category_slug':self.product_category.category_parent.slug,
                                             'category_slug':self.product_category.slug})

所以,当我进入mysite / category / subcategory时,我看到所有产品都属于子类别。这是一个列表(实际上是表格,包括图像,标题等)。 所有图像和标题必须是产品的网址。 这是模板中的一段代码

e {% for product in products %}

                    <tr>
                        <td class="product_name_list">
                            <a href="{{ product.get_absolute_url }}">{{ product.product_name }}</a>
                        </td>
                        <td class="product_article_list">{{ product.product_article }}</td>
                        {% if product.product_main_image  %}
                            <td class="product_image_list"><a href="{{ product.get_absolute_url }}" ><img src='{{ product.product_main_image.url}}' alt=""></a></td>
                        {% else %}
                            <td class="product_image_list"><a href="{{ product.get_absolute_url }}" ><img src='{% static "images/empty.gif" %}' alt=""></a></td>
                        {% endif %}

                        <td class="product_request_list"><a href="#">Запросить</a></td>
                    </tr>

             {% endfor %}

所以,结果,我对数据库有很多查询,因为重复调用了get_absolute_url。

请帮我避免这个。我试图用'get_related()'设置默认的Manager类,但它很愚蠢,但是它没有帮助,因为每个instanse一次又一次地调用方法get_absolute_url。

提前致谢!

1 个答案:

答案 0 :(得分:1)

您可以使用django的cached_property装饰器来解决此问题

from django.utils.functional import cached_property

# You can either use it convert `get_abolute_url` method to property
@cached_property
def get_absolute_url(self):
    return reverse(
        'product_detail', kwargs={
            'slug':self.slug,
            'parent_category_slug':self.product_category.category_parent.slug,
            'category_slug':self.product_category.slug})

# or decorate the method with different name so that you can use both

cached_absolute_url = cached_property(get_absolute_url)

通过这个你可以使用两者,

object.get_absolute_url()

object.cached_absolute_url

cached_property缓存方法的值,这样当你再次调用它时,它不会直接返回整个方法,而是直接返回缓存的值。