Search Suggestions for django elasticsearch - django

I am using the Django Elasticsearch DSL library in order to integrate django with elasticsearch.
I have the search working properly and I am trying to also add the suggestions feature.
my documents.py is the following
# Name of the Elasticsearch index
INDEX = Index('search_movies')
# See Elasticsearch Indices API reference for available settings
INDEX.settings(
number_of_shards=1,
number_of_replicas=1
)
html_strip = analyzer(
'html_strip',
tokenizer="standard",
filter=["standard", "lowercase", "stop", "snowball"],
char_filter=["html_strip"]
)
#INDEX.doc_type
class MovieDocument(DocType):
"""Movie Elasticsearch document."""
id = fields.IntegerField(attr='id')
title = fields.StringField(
analyzer=html_strip,
fields={
'raw': fields.KeywordField(),
'suggest': fields.CompletionField(),
}
)
summary = fields.StringField(
analyzer=html_strip,
fields={
'raw': fields.KeywordField(),
}
)`
I have added the 'suggest': fields.CompletionField(), as I saw it is required in order to get suggestions for that field.
I am trying then to use something similar as to what is shown here. So in my views.py i have the following
client = Elasticsearch()
search_in_title = 'search term goes here'
sreq = Search().using(client).query("multi_match", query=search_in_title, fields=['title', 'summary'])
ssug = sreq.suggest('title_suggestions', search_in_title, term={'field': 'title'})
but the ssug is always empty, so i am guessing i am using it the wrong way.

You need to reference the title.suggest sub-field instead:
ssug = s.suggest('title_suggestions', search_in_title, term={'field': 'title.suggest'})
^
|
add this

Related

Django update or create where field like/beings with

Is it possible to do an update or create where a field beginswith? or like?
I want to update or create a record that begins with a certain string, but everything after the string could be different
For example:
notes_data = 'DB1223 - blah blah, stats : 342, bad : 311'
notes_obj, record = Notes.objects.update_or_create(
defaults={
'notes' : notes_data,
},
'notes' : notes_data.beginswith('DB1223'),
)
You can use __startswith with update_or_create:
notes_obj, created = Notes.objects.update_or_create(
defaults={
'notes': notes_data,
},
notes__startwith='DB1223',
)

filter query results without launching a new sql query

With this code I expected that an sql query would run only on 'all_user_videos' and that the subsequent filter would use the results stored in 'all_user_videos' to do the filter.
# Get all user videos
all_user_videos = Video.objects.filter( author = user )
# User pending videos
pending_videos = all_user_videos.filter( status = 'pending_review' )
# Get user Video that need information
info_required_videos = all_user_videos.filter( status = 'info_required' )
# Get user video on sale
on_sale_videos = all_user_videos.filter( status = 'on_sale' )
context = {
"user_member_profile": instance,
'pending_videos' : pending_videos,
'info_required' : info_required_videos,
'on_sale' : on_sale_videos
}
It seems not to be the case, and that each filter runs a query.
How can I make so that pending_videos, info_required_videos and on_sale_videos don't relaunch queries and use result from the query in 'all_user_videos' ?
You can use regex in a query.
all_user_videos = list(Video.objects.filter(author=user, status__regex=r'^(pending_review|info_required|on_sale)$'))
pending_videos = [i for i in all_user_videos if i.status == 'pending_review']
or
pending_videos = []
for i in all_user_videos:
if i.status == 'pending_review':
pending_videos.append(i)
elif i.status == 'info_required':
...

odoo: printing qweb report using wizard

i have two reports cout_materiel_facture_detail_report.xml (detailed report) and cout_materiel_facture_report.xml (simple report) and have a wizard where the user inputs some data and chooses whether he/she wants to print the simple report or the detailed one. Here is the wizard's class:
class CoutMaterielFactureWizard(models.TransientModel):
_name = 'gc.cout_materiel_facture_wizard'
directeur_parc_id = fields.Many2one('hr.employee', string='Directeur Parc')
procedure = fields.Char(string='Procedure')
version = fields.Char(string='Verion')
date_realisation = fields.Date(string='Date realisation')
# is_landscape = fields.Boolean(string='Mode paysage?')
is_detail = fields.Boolean(string='Version simplifiee?')
#api.multi
def do_toggle_print(self):
cout_materiel = self.env['gc.cout_materiel'].browse(self._context.get('active_id', False))
cout_materiel.write({
'directeur_parc_id': self.directeur_parc_id.id
})
# Print the simple report
if not self.is_detail:
return {
'type': 'ir.actions.report.xml',
'name': 'gestion_cout.cout_materiel_facture_report_template',
'report_name': 'gestion_cout.cout_materiel_facture_report_template',
}
# Print the detailed report
else:
sql = "SELECT SUM(h_sup)+SUM(h_exp),SUM(h_im),count(*),SUM(total), famille FROM gc_cout_materiel_line where " \
"cout_materiel_id =%s group by famille "
self.env.cr.execute(sql, (cout_materiel.id,))
results = self.env.cr.fetchall()
if len(results) > 0:
line_ids = []
for nbht, nbhim, qte, prix_total, famille in results:
line_ids.append((0, 0, {
'famille': famille,
'type': 'VA',
'qte': qte,
'nbr_heures': nbht,
'nbr_heures_im': nbhim,
'nbr_jours': 28,
'prix_unitaire': 'VA',
'prix_total': prix_total,
}))
self.env['gc.cout_materiel_facture_temp'].create({
'chantier_name': cout_materiel.chantier_id.name,
'mois_name': cout_materiel.mois_id.name,
'num_annexe': cout_materiel.num_annexe,
'expediteur': cout_materiel.expediteur,
'destinateur': cout_materiel.destinateur,
'application_date': cout_materiel.application_date,
'date_realisation': self.date_realisation,
'directeur_parc_name': self.directeur_parc_id.name,
'procedure': self.procedure,
'version': self.version,
'prix_total_global': cout_materiel.total_global,
'line_ids': line_ids,
})
return {
'type': 'ir.actions.report.xml',
'name': 'gestion_cout.gc_cout_materiel_facture_detail_report_template',
'report_name': 'gestion_cout.gc_cout_materiel_facture_detail_report_template',
}
But i get this error after i hit the print button
I checked out the database and found both reports are present there.
Any help? please!!
Finally i managed to solve my problem!!
Here is what i did:
I created a method in the wizard model which returns a list of objects that i whant to print and linked the wizard to the qweb report.
Then i called the method from the qweb report using object.my_mehtod() in a t-foreach loop, where object represents the wizard.
With this way i am able to create complex reports and print them easily. One can use this method to get data from several tables and organize the data and retur them as a list.
I hope that it will help someone.
Best regards!!

Fields not appearing while trying to fetch adset using facebook ads sdk 2.5.1(python)

Following is the code which will try to fetch the fields for a given adset id.
The problem is I'm not able to get any fields that I've mentioned. Only id is being seen in the response.
Code :
FacebookAdsApi.init(account_id, "credentials", "access_token")
api = FacebookAdsApi.get_default_api()
api_batch = api.new_batch()
adset = AdSet(fbid=adset_id)
fields = [
AdSet.Field.name,
AdSet.Field.configured_status,
AdSet.Field.effective_status,
AdSet.Field.account_id,
AdSet.Field.campaign_id,
AdSet.Field.daily_budget,
AdSet.Field.start_time,
AdSet.Field.bid_amount,
AdSet.Field.billing_event,
AdSet.Field.optimization_goal,
AdSet.Field.targeting,
AdSet.Field.promoted_object
]
adset = AdSet(str(adset_id))
api = FacebookAdsApi.get_default_api()
api_batch = api.new_batch()
def get_response(success_adset=None):
print "Response is success"
print success_adset.json()
def get_failure(failure_adset=None):
print "Response is failure"
print failure_adset.json()
fn_success = partial(get_response)
fn_failure = partial(get_failure)
adset.remote_read(fields=[AdSet.Field.name], batch=api_batch, success=fn_success, failure=fn_failure)
api_batch.execute()
it doesn't look like you're passing the fields into the remote_read method. In the SDK examples we use the following:
adset.remote_read(fields=[
AdSet.Field.name,
AdSet.Field.configured_status,
AdSet.Field.effective_status,
AdSet.Field.account_id,
AdSet.Field.campaign_id,
AdSet.Field.daily_budget,
AdSet.Field.start_time,
AdSet.Field.bid_amount,
AdSet.Field.billing_event,
AdSet.Field.optimization_goal,
AdSet.Field.targeting,
AdSet.Field.promoted_object
], batch=api_batch, success=fn_success, failure=fn_failure)

How to make parameter optional in Zend Framework Router

I would like to know the .ini config file setup to make a route wherein the page number parameter is optional so that
http://news.mysite.com/national
http://news.mysite.com/national/1
point to the same page.
I have the code as follows
resources.router.routes.news_list.type = "Zend_Controller_Router_Route_Regex"
resources.router.routes.news_list.route = "([a-zA-Z0-9\-]+)/([0-9\-]+)"
resources.router.routes.news_list.defaults.module = "news"
resources.router.routes.news_list.defaults.controller = "index"
resources.router.routes.news_list.defaults.action = "category"
resources.router.routes.news_list.defaults.page = 1
resources.router.routes.news_list.map.1 = "categ"
resources.router.routes.news_list.map.2 = "page"
resources.router.routes.news_list.reverse = "%s/%s"
can some1 help me out with a solution to modify this code to make it work for both urls
You can do this without the regex route using:
routes.news_list.route = ":action/:page"
routes.news_list.defaults.module = "news"
routes.news_list.defaults.controller = "index"
routes.news_list.defaults.action = "category"
routes.news_list.defaults.page = 1
I assume that you want every request to go to the "news" module and the "index" controller. Only the action and the page are variable in the url.
resources.router.routes.news_list.type = "Zend_Controller_Router_Route_Regex"
resources.router.routes.news_list.route = "([a-zA-Z0-9-]+)/?([0-9]+)?"
resources.router.routes.news_list.defaults.module = "news"
resources.router.routes.news_list.defaults.controller = "index"
resources.router.routes.news_list.defaults.action = "category"
resources.router.routes.news_list.defaults.page = 1
resources.router.routes.news_list.map.1 = "categ"
resources.router.routes.news_list.map.2 = "page"
resources.router.routes.news_list.reverse = "%s/%d"
Something like this could work too in case you need to use Regex.