pythonsqldjangodjango-debug-toolbar

get_absolute_url very busy database


When I load a product page, I want other products to be offered on that page. But when generating an absolute url for each product, the database is accessed. Accordingly, if there are 10 products on the page, then there will be + 10 calls to the database How can i reduce the number of queries in the db? It`s my code:

models.py

class Goods(models.Model):
    category = models.ForeignKey(Category,
                                 related_name='goods',
                                 on_delete=models.SET_NULL,
                                 null=True)

    name = models.CharField(max_length=150, db_index=True, verbose_name='название')
    slug = models.CharField(max_length=150, db_index=True, unique=True, verbose_name='Слаг')

    def get_absolute_url(self):
    return reverse('goods_detail', kwargs={"category_slug[enter image description here][1]": self.category.slug, "goods_slug": self.slug})

urls.py

path('<slug:category_slug>/<slug:goods_slug>', views.GoodsDetailView.as_view(), name='goods_detail'),

views.py

class GoodsDetailView(DetailView):
    model = Goods
    context_object_name = 'goods'
    slug_url_kwarg = 'goods_slug'

goods_detail.html

{% for i in  goods.ingredients.all%}<br>
    <a href="{{ i.get_absolute_url }}"> {{ i }}</a>
{% endfor %}

*The photo shows an example if I display 4 objects on a page


Solution

  • Assuming Ingredient has a foreignkey relationship to Goods

    In your views.py class you can preload the information by getting additional context (see docs).

    def get_context_data(self, **kwargs):
        # Call the base implementation first to get a context
        context = super().get_context_data(**kwargs)
        # Add in a QuerySet of all the ingredients related to this object
        context['ingredients'] = Ingredient.objects.filter(goods = self.get_object())
        return context
    

    then you can refer to the new context element in your template

    {% for i in ingredients %}<br>
        <a href="{{ i.get_absolute_url }}"> {{ i }}</a>
    {% endfor %}