I want to search something in unicode character like ŞÇİÖÜ
I define a seach function like that:
def search(request):
from django.db.models import Q
q = request.GET.get("search", "")
k = q.split()
list=[]
for i in k:
query = Q(title__icontains=i) | Q(content__icontains=i)
posts = Post.objects.filter(query).distinct().order_by('date')
list.append(posts)
total = 0
if list[0]:
total += len(list)
return render_to_response('search_results.html', RequestContext(request, {
"list": list,
"q": q,
"total": total,
}))
I have LANGUAGE_CODE = "UTF-8". When I want to search 'Şeker Öçü' it returns nothing ,although I have şeker öçü in posts.
The query string that you obtain from request.GET.get("search", "") is in ISO-8859-8, but Django's default encoding is UTF-8.
You will have to change either DEFAULT_CHARSET or HttpRequest.encoding to ISO-8859-8 to get the correct Unicode data. ( https://docs.djangoproject.com/en/dev/ref/settings/#default-charset )
Related
I'd like to generate a URL for AWS Cloud Watch Logs Insights page where I can customize the following parameters:
The query string
The log groups I'd like to search with-in
The time range
I couldn't find any official documentation for the structure of the URL.
Also no API (at least not in boto3) would help me in this.
Here is an example:
https://eu-west-1.console.aws.amazon.com/cloudwatch/home?region=eu-west-1#logsV2:logs-insights$3FqueryDetail$3D$257E$2528end$257E$25272021-07-18T20*3a59*3a59.000Z$257Estart$257E$25272021-07-15T21*3a00*3a00.000Z$257EtimeType$257E$2527ABSOLUTE$257Etz$257E$2527Local$257EeditorString$257E$2527fields*20*40timestamp*2c*20*40message*0a*7c*20sort*20*40timestamp*20desc*0a*7c*20filter*20*40message*20*3d*7e*20*22Exception*22*0a*7c*20limit*20200$257EisLiveTail$257Efalse$257EqueryId$257E$2527####$257Esource$257E$2528$257E$2527*2faws*2flambda*2f######$2529$2529$26tab$3Dlogs
What is the encoding used to generate the URL above?
I'm thinking about simply replace the strings above with the desired params, any better way to achieve this ?
Replacing the strings in the URL isn't that direct, I did the following in Python that will generate link for the logs insights page:
def generate_cloudwatch_url(log_groups, query):
def escape(s):
for c in s:
if c.isalpha() or c.isdigit() or c in ["-", "."]:
continue
c_hex = "*{0:02x}".format(ord(c))
s = s.replace(c, c_hex)
return s
def gen_log_insights_url(params):
S1 = "$257E"
S2 = "$2528"
S3 = "$2527"
S4 = "$2529"
res = f"{S1}{S2}"
for k in params:
value = params[k]
if isinstance(value, str):
value = escape(value)
elif isinstance(value, list):
for i in range(len(value)):
value[i] = escape(value[i])
prefix = S1 if list(params.items())[0][0] != k else ""
suffix = f"{S1}{S3}"
if isinstance(value, list):
value = "".join([f"{S1}{S3}{n}" for n in value])
suffix = f"{S1}{S2}"
elif isinstance(value, int) or isinstance(value, bool):
value = str(value).lower()
suffix = S1
res += f"{prefix}{k}{suffix}{value}"
res += f"{S4}{S4}"
QUERY = f"logsV2:logs-insights$3Ftab$3Dlogs$26queryDetail$3D{res}"
return f"https://eu-west-1.console.aws.amazon.com/cloudwatch/home?region=eu-west-1#{QUERY}"
query_vars = {"sample":"value"}
query = "\n".join([f'| filter {k}="{v}"' for (k, v) in query_vars.items()])
params = {
"end": 0, # "2021-07-18T20:00:00.000Z",
"start": -60 * 60 * 24, # "2021-07-15T21:00:00.000Z",
"unit": "seconds",
"timeType": "RELATIVE", # "ABSOLUTE", # OR RELATIVE and end = 0 and start is negative seconds
"tz": "Local", # OR "UTC"
"editorString": f"fields #timestamp, #message\n| sort #timestamp desc\n{query}\n| limit 200",
"isLiveTail": False,
"source": [f"/aws/lambda/{lg}" for lg in log_groups],
}
return gen_log_insights_url(params)
I know it's aweful implementation, but it works!
In Django admin, if I want to display a list of Iron and their respective formatted weights, I would have to do this.
class IronAdmin(admin.ModelAdmin):
model = Iron
fields = ('weight_formatted',)
def weight_formatted(self, object):
return '{0:.2f} Kg'.format(object.weight)
weight_formatted.short_description = 'Weight'
I.e: 500.00 Kg
The problem with this however is that I would have to write a method for every field that I want to format, making it redundant when I have 10 or more objects to format.
Is there a method that I could override to "catch" these values and specify formatting before they get rendered onto the html? I.e. instead of having to write a method for each Admin class, I could just write the following and have it be formatted.
class IronAdmin(admin.ModelAdmin):
model = Iron
fields = ('weight__kg',)
def overriden_method(field):
if field.name.contains('__kg'):
field.value = '{0:.2f} Kg'.format(field.value)
I.e: 500.00 Kg
After hours scouring the source , I finally figured it out! I realize this isn't the most efficient code and it's probably more trouble than it's worth in most use cases but it's enough for me. In case anyone else needs a quick and dirty way to do it:
In order to automate it, I had to override django.contrib.admin.templatetags.admin_list.result_list with the following:
def result_list_larz(cl):
"""
Displays the headers and data list together
"""
resultz = list(results(cl)) # Where we override
""" Overriding starts here """
""" Have to scrub the __kg's as result_header(cl) will error out """
for k in cl.list_display:
cl.list_display[cl.list_display.index(k)] = k.replace('__kg','').replace('__c','')
headers = list(result_headers(cl))
num_sorted_fields = 0
for h in headers:
if h['sortable'] and h['sorted']:
num_sorted_fields += 1
return {'cl': cl,
'result_hidden_fields': list(result_hidden_fields(cl)),
'result_headers': headers,
'num_sorted_fields': num_sorted_fields,
'results': resultz}
Then overriding results(cl)'s call to items_for_result() wherein we then override its call to lookup_field() as follows:
def lookup_field(name, obj, model_admin=None):
opts = obj._meta
try:
f = _get_non_gfk_field(opts, name)
except (FieldDoesNotExist, FieldIsAForeignKeyColumnName):
# For non-field values, the value is either a method, property or
# returned via a callable.
if callable(name):
attr = name
value = attr(obj)
elif (model_admin is not None and
hasattr(model_admin, name) and
not name == '__str__' and
not name == '__unicode__'):
attr = getattr(model_admin, name)
value = attr(obj)
""" Formatting code here """
elif '__kg' in name or '__c' in name: # THE INSERT FOR FORMATTING!
actual_name = name.replace('__kg','').replace('__c', '')
value = getattr(obj, actual_name)
value = '{0:,.2f}'.format(value)
prefix = ''
postfix = ''
if '__kg' in name:
postfix = ' Kg'
elif '__c' in name:
prefix = 'P'
value = '{}{}{}'.format(prefix, value, postfix)
attr = value
else:
attr = getattr(obj, name)
if callable(attr):
value = attr()
else:
value = attr
f = None
""" Overriding code END """
else:
attr = None
value = getattr(obj, name)
return f, attr, value
I did the code for insert records from so_parts table to so_bo table using Query...How can I use ORM method to do this kind of job. Is there any other way(best)to do that? Here is my code`
`
#api.multi
def save_rapair_parts(self, vals):
#get todays date and convert it to string
created_date = datetime.datetime.today().strftime("%m/%d/%Y")
str_date = str(created_date)
so_p_id = self.so_p_id.id
bo_status = self.bo_status
so_part_t = self.so_part_t
so_part_sno = self.so_part_sno
product = self.so_part_product
product_str = 'Repair '+str(product)
part_id = self.id
bench_order_table.search(['id','bo_sno','created_date','bo_number','rep_description','bo_status'])
#insert details intoso bench orders
`
if so_part_t=='r_b':
try:
sequence = self.env['ir.sequence'].next_by_code('so.benchorder') or '/'
str_sequence = str(sequence)
query = """SELECT so_work_authorization FROM my_depots_so WHERE id=%d """ % (so_p_id)
self.env.cr.execute(query)
result = self.env.cr.fetchall()
result_number = json.dumps(result, ensure_ascii=False)
strip_number = result_number.strip('\' \" [] ')
work_auth_no = str(strip_number)
work_auth_no += "-"
work_auth_no += str_sequence
insert ="""INSERT INTO my_depots_so_bo(id,so_bo_id,bo_sno,created_date,bo_number,rep_description,bo_status) values %s """
parameters = (part_id,so_p_id,so_part_sno,str_date,work_auth_no,product_str,bo_status)
self.env.cr.execute(insert,(parameters,))
my_depots_bo(id,bo_sno,created_date,bo_number,rep_description,bo_status) values %s """
# self.env.cr.execute(insert_query, (parameters,))
except Exception:
print "Error in inserting values"`
yes there is a better way because when you use ORM
method you also checks access right for user to:
for your select query:
rec = self.env['my.depots.so'].search_read(['id', '=', so_p_id], ['so_work_authorization'])
if rec:
rec = rec[0] # search_read return a list of dictionary
so_work_authorization = rec['so_work_authorization']
# and do what ever you want with the result
# to create
# call create method witch accept a dictionary
# field_name : value
new_rec = self.env['my.depots.so.bo'].create({
'so_bo_id': so_p_id, # many2one must be an integer value
'bo_sno': bo_nso_value,
'bo_number': value_of_number,
# ....
# ....
# add al field
}) # create return the new created record as model object
for inserting use: self.env['model.name'].create(vals)
for updating use : self.env['model.name'].write(vals)
using ORM method makes sure that user don't pass the security access rigths
Hope you get the idea
from django.db.models import Q
MODULES_USERS_PERMS = {
MODULE_METHOD: [],
MODULE_NEWS: [],
MODULE_PROJECT: ['created_by', 'leader'],
MODULE_TASK: [],
MODULE_TICKET: [],
MODULE_TODO: []
}
filter_fields = MODULES_USERS_PERMS[MODULE_PROJECT]
perm_q = map(lambda x: Q(x=user), filter_fields)
if perm_q: #sum(perm_q)
if len(perm_q) == 1:
return perm_q[0]
elif len(perm_q) == 2:
return perm_q[0] | perm_q[1]
elif len(perm_q) == 3:
return perm_q[0] | perm_q[1] | perm_q[2]
I do not know how to describe in words what is required by code, I hope he speaks for itself.
I need to make a filter from the list of objects.
Needless code is not working.
UPDATE:
code, that looks better, but not working too:
filters = ['created_by', 'leader']
filter_params = Q()
for filter_obj in filters:
filter_params = filter_params | Q(filter_obj=user)
FieldError at /projects/
Cannot resolve keyword 'filter_obj' into field. Choices are:
begin_time, comment, created_at, created_by, created_by_id, end_time,
id, leader, leader_id, name, project_task, status, ticket_project
If you're looking to combine an unknown number of Q objects:
import operator
perm_q = reduce(operator.or_, perm_q)
Or:
summed_q = perm_q[0]
for new_term in perm_q[1:]:
summed_q = summed_q | new_term
Which does the same thing, just more explicitly.
Based on your edit - you need to turn the string contained in your filter_obj variable into a keyword argument. You can do this by creating a dictionary to use as the keyword arguments for the Q constructor:
filters = ['created_by', 'leader']
filter_params = Q()
for filter_obj in filters:
kwargs = {filter_obj: user}
filter_params = filter_params | Q(**kwargs)
I've got this complex filtering mechanism...
d = copy(request.GET)
d.setdefault('sort_by', 'created')
d.setdefault('sort_dir', 'desc')
form = FilterShipmentForm(d)
filter = {
'status': ShipmentStatuses.ACTIVE
}
exclude = {}
if not request.user.is_staff:
filter['user__is_staff'] = False
if request.user.is_authenticated():
exclude['user__blocked_by__blocked'] = request.user
if form.is_valid():
d = form.cleaned_data
if d.get('pickup_city'): filter['pickup_address__city__icontains'] = d['pickup_city']
if d.get('dropoff_city'): filter['dropoff_address__city__icontains'] = d['dropoff_city']
if d.get('pickup_province'): filter['pickup_address__province__exact'] = d['pickup_province']
if d.get('dropoff_province'): filter['dropoff_address__province__exact'] = d['dropoff_province']
if d.get('pickup_country'): filter['pickup_address__country__exact'] = d['pickup_country']
if d.get('dropoff_country'): filter['dropoff_address__country__exact'] = d['dropoff_country']
if d.get('min_price'): filter['target_price__gte'] = d['min_price']
if d.get('max_price'): filter['target_price__lte'] = d['max_price']
if d.get('min_distance'): filter['distance__gte'] = d['min_distance'] * 1000
if d.get('max_distance'): filter['distance__lte'] = d['max_distance'] * 1000
if d.get('available_on'): # <--- RELEVANT BIT HERE ---
filter['pickup_earliest__lte'] = d['available_on'] # basically I want "lte OR none"
filter['pickup_latest__gte'] = d['available_on']
if d.get('shipper'): filter['user__username__iexact'] = d['shipper']
order = ife(d['sort_dir'] == 'desc', '-') + d['sort_by']
shipments = Shipment.objects.filter(**filter).exclude(**exclude).order_by(order) \
.annotate(num_bids=Count('bids'), min_bid=Min('bids__amount'), max_bid=Max('bids__amount'))
And now my client tells me he wants pickup/drop-off dates to be 'flexible' as an option. So I've updated the DB to allow dates to be NULL for this purpose, but now the "available for pickup on" filter won't work as expected. It should include NULL/None dates. Is there an easy fix for this?
Flip the logic and use exclude(). What you really want to do is exclude any data that specifies a date that doesn't fit. If pickup_latest and pickup_earliest are NULL it shouldn't match the exclude query and wont be removed. Eg
exclude['pickup_latest__lt'] = d['available_on']
exclude['pickup_earliest__gt'] = d['available_on']
Most database engines don't like relational comparisons with NULL values. Use <field>__isnull to explicitly check if a value is NULL in the database, but you'll need to use Q objects to OR the conditions together.
Don't think that's actually a django-specific question. Variable 'd' is a python dictionary, no? If so, you can use this:
filter['pickup_latest__gte'] = d.get('available_on', None)