etianen / django-watson

Full-text multi-table search application for Django. Easy to install and use, with good performance.
BSD 3-Clause "New" or "Revised" License
1.21k stars 129 forks source link

Why object.get_absolute_url hits the database each time? #118

Closed chogarcia closed 8 years ago

chogarcia commented 9 years ago

Why object.get_absolute_url hits the database each time?

etianen commented 9 years ago

Could you provide more information about your issue?

Specifically what python snippet results in the database being hit?

On Thu, 6 Aug 2015 at 15:44 Cho Garcia notifications@github.com wrote:

Why object.get_absolute_url hits the database each time?

— Reply to this email directly or view it on GitHub https://github.com/etianen/django-watson/issues/118.

chogarcia commented 9 years ago

for example my model method is:

    def get_absolute_url(self):
        return reverse('article', args=[str(self.id)])

So when I do:

              {% for obj in searchentry_list %}
                <div class="item">
                  <a href="{{ obj.object.get_absolute_url }}">
                    <h4>{{ obj.title }}</h4>

                    {% if obj.object.intro %}
                      {{ obj.object.intro }}
                    {% elif obj.object.excerpt %}
                      {{ obj.object.excerpt }}
                    {% endif %}
                  </a>
                </div>
              {% endfor %}

Is making as many queries as results.

The other issue is that when I try to store additional information:

        watson.register(
            Article.objects.filter(is_published=True),
            fields=(
                'title',
                'excerpt',
                'body',
                'author',
            ),
            store=('get_absolute_url')
        )

I got: UnicodeDecodeError: 'ascii' codec can't decode byte 0xd9 in position 10: ordinal not in range(128)

etianen commented 9 years ago

There are a couple of issues here.

When you access obj.object, it looks up the object from the database. This can be mitigated by calling prefetch_related("object") on searchentry_list, but a bug in Django sometimes seems to make obj.object None, randomly. So use at your peril.

You can mitigate this by storing extra fields on your search entry object. However, it looks like one of the fields you're trying to store isn't returning a unicode object, so you might want to look into that.

The get_absolute_url should already be stored on the search entry, and accesible as obj.get_absolute_url in the template.

On Thu, 6 Aug 2015 at 16:15 Cho Garcia notifications@github.com wrote:

for example my model method is:

def get_absolute_url(self):
    return reverse('article', args=[str(self.id)])

So when I do:

          {% for obj in searchentry_list %}
            <div class="item">
              <a href="{{ obj.object.get_absolute_url }}">
                <h4>{{ obj.title }}</h4>

                {% if obj.object.intro %}
                  {{ obj.object.intro }}
                {% elif obj.object.excerpt %}
                  {{ obj.object.excerpt }}
                {% endif %}
              </a>
            </div>
          {% endfor %}

Is making as many queries as results.

The other issue is that when I try to store additional information:

    watson.register(
        Article.objects.filter(is_published=True),
        fields=(
            'title',
            'excerpt',
            'body',
            'author',
        ),
        store=('get_absolute_url')
    )

I got: UnicodeDecodeError: 'ascii' codec can't decode byte 0xd9 in position 10: ordinal not in range(128)

— Reply to this email directly or view it on GitHub https://github.com/etianen/django-watson/issues/118#issuecomment-128407554 .

chogarcia commented 9 years ago

{{ obj.get_absolute_url }} does not seems to work properly with i18n urls.

It returns /en-us/article/ instead of the right one from the model method /en/article/

chogarcia commented 9 years ago

where would you call prefetch_related("object") ?

chogarcia commented 9 years ago

I am doing according to the docs and no matter what I try to store as additional info, I get the same error

UnicodeDecodeError: 'ascii' codec can't decode byte 0xd9 in position 10: ordinal not in range(128)

etianen commented 9 years ago

Ah, yes, for i18n to work, you'll need to use obj.object.get_absolute_url.

You're unicode error is being caused by one of your fields ('title', 'excerpt', 'body', 'author') containing a non-unicode string. Also check you're model's unicode method, another common area where this can go wrong. For me to help more, I'll need to see a full traceback.

Call searchentry_list.prefetch_related("object") in your view, or in a template tag.

On Thu, 6 Aug 2015 at 17:39 Cho Garcia notifications@github.com wrote:

I am doing according to the docs and no matter what I try to store as additional info, I get the same error

UnicodeDecodeError: 'ascii' codec can't decode byte 0xd9 in position 10: ordinal not in range(128)

Reply to this email directly or view it on GitHub https://github.com/etianen/django-watson/issues/118#issuecomment-128432235 .