2017-09-25 3 views
1

J'utilise par défaut la base de données backend pour la fonction de recherche dans mon projet:Bergeronnette recherche par défaut ne fonctionne pas avec des champs non anglais

from __future__ import absolute_import, unicode_literals 

from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator 
from django.shortcuts import render 

from home.models import BlogPage, get_all_tags 
from wagtail.wagtailsearch.models import Query 


def search(request): 
    search_query = request.GET.get('query', None) 
    page = request.GET.get('page', 1) 

    # Search 
    if search_query: 
     search_results = BlogPage.objects.live().search(search_query) 
     query = Query.get(search_query) 

     # Record hit 
     query.add_hit() 
    else: 
     search_results = BlogPage.objects.none() 

    # Pagination 
    paginator = Paginator(search_results, 10) 
    try: 
     search_results = paginator.page(page) 
    except PageNotAnInteger: 
     search_results = paginator.page(1) 
    except EmptyPage: 
     search_results = paginator.page(paginator.num_pages) 

    return render(request, 'search/search.html', { 
     'search_query': search_query, 
     'blogpages': search_results, 
     'tags': get_all_tags() 
    }) 

blogpage:

class BlogPage(Page): 
    date = models.DateField("Post date") 
    intro = models.CharField(max_length=250) 
    body = StreamField([ 
     ('heading', blocks.CharBlock(classname="full title")), 
     ('paragraph', blocks.RichTextBlock()), 
     ('image', ImageChooserBlock()), 
     ('code', CodeBlock()), 
    ]) 
    tags = ClusterTaggableManager(through=BlogPageTag, blank=True) 

    search_fields = Page.search_fields + [ 
     index.SearchField('intro'), 
     index.SearchField('body'), 
    ] 
    ... 

Et la recherche fonctionne bien que si body les champs dans le modèle BlogPage sont en anglais, si j'essaie d'utiliser des mots russes dans les champs body alors il ne cherche rien. J'ai regardé la base de données et je vois que BlogPage a champ body comme ceci:

[{"value": "\u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0439", "id": "3343151a-edbc-4165-89f2-ce766922d68e", "type": "heading"}, {"value": "<p>\u0442\u0435\u0441\u0442\u0438\u043f\u0440</p>", "id": "22d3818d-8c69-4d72-967e-7c1f807e80b2", "type": "paragraph"}] 

Ainsi, le problème est Bergeronnette enregistre les champs Streamfield sous forme de caractères unicode, si je change manuellement phpmyadmin à ceci:

[{"value": "Тест", "id": "3343151a-edbc-4165-89f2-ce766922d68e", "type": "heading"}, {"value": "<p>Тестовый</p>", "id": "22d3818d-8c69-4d72-967e-7c1f807e80b2", "type": "paragraph"}] 

Ensuite, la recherche commence à fonctionner, alors peut-être quelqu'un sait comment empêcher widtail d'enregistrer Streamfield champs en unicode?

+0

Vous ne mentionnaient pas quel module de recherche que vous utilisez. Utilisez-vous Elasticsearch? J'ai intégré avec succès la recherche en langue allemande en utilisant Elasticsearch. Il semble que vous n'ayez pas [ajouté de champs supplémentaires à l'index] (http://docs.wagtail.io/en/v1.12.2/topics/search/indexing.html#indexing-extra-fields). Ou avez-vous simplement omis la déclaration search_fields de '' BlogPage''? – Moritz

+0

J'ai spécifié search_fields (ajoutez ces lignes à la question), et j'imagine que j'utilise le backend de base de données par défaut pour la recherche. Que dois-je faire pour passer à Elasticsearch? Je devrais changer la base de données à elastichsearch et changer la configuration de wagtailsearch? – Alexey

+0

Vous devriez jeter un coup d'œil à [docs] (http://docs.wagtail.io/en/v1.12.2/topics/search/backends.html#elasticsearch-backend) pour commencer. Cependant, le backend PostgreSQL est plus facile à configurer (http://docs.wagtail.io/en/v1.12.2/reference/contrib/postgres_search.html#postgres-search). – Moritz

Répondre

1

Je déteste cette solution de contournement, mais je décide simplement d'ajouter un autre champs search_body et search_intro et recherche ensuite les utiliser:

class BlogPage(Page): 
    date = models.DateField("Post date") 
    intro = models.CharField(max_length=250) 
    body = StreamField([ 
     ('heading', blocks.CharBlock(classname="full title")), 
     ('paragraph', blocks.RichTextBlock()), 
     ('image', ImageChooserBlock()), 
     ('code', CodeBlock()), 
    ]) 
    search_intro = models.CharField(max_length=250) 
    search_body = models.CharField(max_length=50000) 
    tags = ClusterTaggableManager(through=BlogPageTag, blank=True) 

    def main_image(self): 
     gallery_item = self.gallery_images.first() 
     if gallery_item: 
      return gallery_item.image 
     else: 
      return None 

    def get_context(self, request): 
     context = super(BlogPage, self).get_context(request) 
     context['tags'] = get_all_tags() 
     context['page_url'] = urllib.parse.urljoin(BASE_URL, self.url) 
     return context 

    def save(self, *args, **kwargs): 
     if self.body.stream_data and isinstance(
       self.body.stream_data[0], tuple): 
      self.search_body = '' 
      for block in self.body.stream_data: 
       if len(block) >= 2: 
        self.search_body += str(block[1]) 
     self.search_intro = self.intro.lower() 
     self.search_body = self.search_body.lower() 
     return super().save(*args, **kwargs) 

    search_fields = Page.search_fields + [ 
     index.SearchField('search_intro'), 
     index.SearchField('search_body'), 
    ] 
    ... 

Recherche/views.py:

def search(request): 
    search_query = request.GET.get('query', None) 
    page = request.GET.get('page', 1) 

    # Search 
    if search_query: 
     search_results = BlogPage.objects.live().search(search_query.lower()) 
     query = Query.get(search_query) 
    ... 
0

Alexey, je vous remercie !

Mais j'ai eu double appel de enregistrer méthode.

Et j'utiliser ce code:

def save(self, *args, **kwargs): 
    search_body = '' 
    if self.blog_post_body.stream_data and isinstance(
      self.blog_post_body.stream_data[0], dict): 
     for block in self.blog_post_body.stream_data: 
      if block.get('type', '') in ('some_header', 'some_text'): 
       search_body += str(block['value']) 
    self.search_body = search_body 
    super(BlogPost, self).save(*args, **kwargs) 
+0

Oui, peut-être votre code est meilleur, mais je pense que ce problème est lié à SqLite db, le problème a disparu quand je suis passé à postgres, donc je pense qu'il vaut mieux ne pas utiliser cette approche – Alexey