i want to create a search in django which have order by istartswith first than icontains - python-3.x

def autocomplete(request):
template_name='searchresults.html'
if 'term' in request.GET:
qs=Post.objects.filter(Q(title__istartswith=request.GET.get('term'))|Q(content__icontains=request.GET.get('term')))
titles=list()
for post in qs:
titles.append(post.title)
return JsonResponse(titles, safe=False)
return render(request, template_name)
How can I can order them ins such a way that if it begins with term order it as first and the one that contains it but does not begin with it as second

You can make use of .union(…) [Django-doc]:
term = request.GET.get('term')
qs = Post.objects.filter(
title__istartswith=term
).union(Post.objects.filter(
content__icontains=term
))
or with an .annotate(…) [Django-doc]:
from django.db.models import BooleanField, ExpressionWrapper, Q
term = request.GET.get('term')
qs = Post.objects.filter(
Q(title__istartswith=term) | Q(content__icontains=term)
).annotate(
is_start=ExpressionWrapper(
Q(title__istartswith=term),
output_field=BooleanField()
)
).order_by('-is_start')

Related

I have to make a code taking a name and turning it into a last name, first initial and middle initial format

I have to make a code taking a name and turning it into a last name, first initial, middle initial format. My code works assuming there is a middle name but breaks if not provided a middle name. Is there a way to ignore not having a middle name and to just default to last name and first initial? I'm super new to python3 so I'm sorry if my code is uber bad.
Heres my code :
your_name = input()
broken_name = your_name.split()
first_name = broken_name[0]
middle_name = broken_name[1]
last_name = broken_name[2]
middle_in = middle_name[0]
first_in = first_name[0]
print(last_name+',',first_in+'.'+middle_in+'.' )
You can use an if else statement to check how long broken_name is.
Try:
your_name = input()
broken_name = your_name.split()
if len(broken_name) > 2:
first_name = broken_name[0]
middle_name = broken_name[1]
last_name = broken_name[2]
middle_in = middle_name[0]
first_in = first_name[0]
print(last_name+', ',first_in+'. '+middle_in+'.'
else:
first_name = broken_name[0]
last_name = broken_name[1]
first_in = first_name[0]
print(last_name+', ',first_in+'.')
Another option:
def get_pretty_name_str(names):
splited_names = names.split()
last_name = splited_names.pop(-1)
result = f'{last_name},'
while splited_names:
n = splited_names.pop(0)
result += f'{n}.'
return result
print(get_pretty_name_str('First Middle Last')) # Last,First.Middle.
print(get_pretty_name_str('First Last')) # Last,First.

How can I filter search results using Scrapy

I am new to scraping and I am trying to scrape data from this website https://seffaflik.epias.com.tr/transparency/uretim/gerceklesen-uretim/gercek-zamanli-uretim.xhtml
When I try to get data without applying filters everything is working. But the data I need should be for a specific power plant and date. I am getting a hard time finding why I cannot apply the filters.
from scrapy.http import FormRequest
from ..items import EpiasscrapingItem
class EpiasSpider(scrapy.Spider):
name = 'epias'
start_urls =[
'https://seffaflik.epias.com.tr/transparency/uretim/gerceklesen-uretim/gercek-zamanli-uretim.xhtml'
]
def parse(self, response):
return FormRequest.from_response(response, formdata = {
'j_idt205':'j_idt205',
'j_idt205:date1_input' : '20.03.2021',
'j_idt205:date2_input' : '20.03.2021',
'j_idt205:powerPlant_input' : '2614',
}, callback=self.start_scraping)
def start_scraping(self,response):
items = EpiasscrapingItem()
table_epias = response.css('.ui-datatable-odd')
for epias in table_epias:
date = epias.css('.ui-widget-content .TexAlCenter:nth-child(1)').css('::text').extract()
time = epias.css('.ui-widget-content .TexAlCenter:nth-child(2)').css('::text').extract()
biogas = epias.css('.ui-widget-content .TexAlCenter:nth-child(15)').css('::text').extract()
items['date'] = date
items['time'] = time
items['biogas'] = biogas
yield items```
You forgot to include javax.faces.ViewState and few other fields within parameters supposed to be sent with post requests. You can now change the value of date1_input, date2_input and powerPlant_input to fetch the relevant content. The following script should work:
class EpiasSpider(scrapy.Spider):
name = 'epias'
start_urls = [
'https://seffaflik.epias.com.tr/transparency/uretim/gerceklesen-uretim/gercek-zamanli-uretim.xhtml'
]
post_url = 'https://seffaflik.epias.com.tr/transparency/uretim/gerceklesen-uretim/gercek-zamanli-uretim.xhtml'
def parse(self, response):
payload = {
'j_idt205': 'j_idt205',
'j_idt205:date1_input': '11.02.2021',
'j_idt205:date2_input': '20.03.2021',
'j_idt205:powerPlant_focus': '',
'j_idt205:powerPlant_input': '2336',
'j_idt205:goster': '',
'j_idt205:dt_rppDD': '24',
'javax.faces.ViewState': response.css(".ContainerIndent input[name='javax.faces.ViewState']::attr(value)").get()
}
yield scrapy.FormRequest(self.post_url,formdata=payload,callback=self.parse_content)
def parse_content(self,response):
for epias in response.css('.ui-datatable-odd'):
items = {}
date = epias.css('tr.ui-widget-content > .TexAlCenter:nth-child(1)::text').get()
time = epias.css('tr.ui-widget-content > .TexAlCenter:nth-child(2)::text').get()
total = epias.css('tr.ui-widget-content > .TexAlCenter:nth-child(3)::text').get()
items['date'] = date
items['time'] = time
items['total'] = total
yield items

i have added a field in existing module "hr.payslip" from my module.How to show the data of that field

an existing module is present i.e hr.payslip,In that module i have added a field from my module . now i want to display the value of that field in hr.payslip module.
models/emailpayslip.py
#api.multi #Decorate a record-style method where 'self' is a recordset. The method typically defines an operation on records.
def send_email(self):
ir_model_data = self.env['ir.model.data']
payslip_obj = self.env['hr.payslip']
ids = self.env.context.get('active_ids', [])
ctx = dict()
employee_name = ''
for id_vals in ids:
payslip_browse = payslip_obj.browse(id_vals)
global email
email = payslip_browse.employee_id.work_email
store_email.sql_example(self,email)#calling method of store_email model
if payslip_browse.employee_id.work_email:
template_id = ir_model_data.get_object_reference('Payslip', 'email_template_payslip')[1]
ctx.update({
'default_model': 'hr.payslip',
'default_res_id': payslip_browse.id,
'default_use_template': bool(template_id),
'default_template_id': template_id,
'default_composition_mode': 'comment',
'email_to': payslip_browse.employee_id.work_email,
})
mail_id = self.env['mail.template'].browse(template_id).with_context(ctx).send_mail(payslip_browse.id, True)
This model is used to create a new table in database and store email to which the payslip is send and date of payslip send
class store_email(models.Model):
_name = "store.email"
sendemail = fields.Char(
string='Send Email',
default=lambda self: self._get_default_name(),
)
no_of_times = fields.Integer(string='No of Times')
date_of_email_send = fields.Date(
string="Date of Email",
default=lambda self: fields.datetime.now())
#api.model
def _get_default_name(self):
return "test"
#api.multi
def sql_example(self,temp):
dob = datetime.today()
self.env.cr.execute("SELECT * FROM store_email WHERE sendemail = %s",(temp,))
res = self.env.cr.fetchall()
if res == []:
count = 1
self.env.cr.execute("INSERT INTO store_email (sendemail,no_of_times,date_of_email_send) VALUES (%s,%s,%s)",(temp,count,dob))
self.env.cr.commit()
else:
for x in res:
count = x[7] + 1
self.env.cr.execute("UPDATE store_email SET date_of_email_send=%s,no_of_times=%s WHERE sendemail=%s",(dob,count,temp))
self.env.cr.commit()
Model to add a field in hr.payslip ,Which show last payslip send date
class Add_Field(models.Model):
_inherit = "hr.payslip"
last_payslip_send = fields.Date(string='Last Payslip Send')
#api.multi
def last_send_payslip(self):
self.env.cr.execute("SELECT * FROM store_email WHERE sendemail=%s",(email,))
res = self.env.cr.fetchall()
my addfile.xml
add_newfield
screenshort of the page where i have added the field
this page cntain the screenshort
You can use compute or default function to load value in to field or you can also pass value while creating record
default function example:
name = fields.Char(
string='Name',
default=lambda self: self._get_default_name(),
)
#api.model
def _get_default_name(self):
return "test"
Refer this link for computed fields

Python-MySQL : removing single quotes around variable values in query while running db.execute(str, vars)

I am running this code
def details(self, dbsettings, payload):
res = None
with UseDatabase(dbsettings) as db:
sql = "select * from %(tablename)s where userid = %(userid)s"
result = db.run_query_vals(sql, payload)
res = result.fetchall()
return res
but get an error
SQLError: 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ''statuser' where userid = '14'' at line 1
The arguments being passed are :
sql = "select * from %(tablename)s where userid = %(userid)s"
payload = {'tablename' : 'statuser', 'userid' : 14}
As far as I understand, the query being passed to MySQL is along the lines of
select * from 'statuser' where userid = '14'
which is where I get the error; the tablename isnt supposed to be enclosed in quotes. How do I have the name included without the quotes/make them backquotes?
(I don't want to hard-code the table name - this is a variable and is initialised according to different parameters during class creation). Any help here?
You can use the .format() from string in python:
def details(self, dbsettings, payload):
res = None
with UseDatabase(dbsettings) as db:
sql = "select * from {tablename} where userid = {userid}"
sql = sql.format(**payload)
# result = db.run_query_vals(sql, payload) # Method to run query
res = result.fetchall()
return res
I encountered the same problem in pymysql and have figured out a solution:
rewrite the escape method in class 'pymysql.connections.Connection', which obviously adds "'" arround your string.
don't know whether it will help in your case, just sharing a possible way
similiar question: How to remove extra quotes in pymysql
Here's my code:
from pymysql.connections import Connection, converters
class MyConnect(Connection):
def escape(self, obj, mapping=None):
"""Escape whatever value you pass to it.
Non-standard, for internal use; do not use this in your applications.
"""
if isinstance(obj, str):
return self.escape_string(obj) # by default, it is :return "'" + self.escape_string(obj) + "'"
if isinstance(obj, (bytes, bytearray)):
ret = self._quote_bytes(obj)
if self._binary_prefix:
ret = "_binary" + ret
return ret
return converters.escape_item(obj, self.charset, mapping=mapping)
config = {'host':'', 'user':'', ...}
conn = MyConnect(**config)
cur = conn.cursor()

Get id of a record with the lowest sequence

I have this class
name = fields.Char("Name")
sequence = fields.Integer("Sequence")
description = fields.Text("Description")
I need a search method to find the id with lower sequence
res = self.env['your.model'].search([], limit=1, order='sequence desc')
should to the trick
I think this search function would do the trick.
def _find_register(self, operator, value):
lowest_sequence_id = False
lowest_sequence = False
for state in self.env['ags.traffic.operation.state'].search([('id','>',0)]):
if not lowest_sequence:
lowest_sequence_id = state.id
lowest_sequence = state.sequence
elif state.sequence < lowest_sequence:
lowest_sequence = state.sequence
return [('id', '=', lowest_sequence_id)]

Resources