Looking for something more pythonic - django

This looks really ugly, it there a way to make it look more pythonic?
if self.cleaned_data['string1_val'] == '' and latestSI.string1_val is None :
if self.cleaned_data['string2_val'] == '' and latestSI.string2_val is None :
return False
elif self.cleaned_data['string2_val'] == latestSI.string2_val :
return False
else:
return True
elif self.cleaned_data['string1_val'] == latestSI.string1_val :
if self.cleaned_data['string2_val'] == '' and latestSI.string2_val is None :
return False
elif self.cleaned_data['string2_val'] == latestSI.string2_val :
return False
else:
return True
else:
return True

def eq(x,y):
return x == ('' if y is None else y)
if eq(self.cleaned_data['string1_val'],latestSI.string1_val):
return not eq(self.cleaned_data['string2_val'],latestSI.string2_val)
Hm. It looks like the question has changed. With the addition of the final else: True, the logic can be changed to
return not (eq(self.cleaned_data['string1_val'],latestSI.string1_val)
and eq(self.cleaned_data['string2_val'],latestSI.string2_val))

All your issues stem from Nones. Clean them up and your logic becomes trivial.
cd1 = self.cleaned_data['string1_val']
lsi1 = latestSI.string1_val
cd2 = self.cleaned_data['string2_val']
lsi2 = latestSI.string2_val
if lsi1 is None:
lsi1 = ''
if lsi2 is None:
lsi2 = ''
return not (cd1 == lsi1 and cd2 == lsi2)

I think this expression is equivalent (I can't test it, since I don't have access to the rest of your code). But, it's really long and hard to understand, I'd rather leave it untouched if I were you:
if (self.cleaned_data['string1_val'] == latestSI.string1_val) or (not self.cleaned_data['string1_val'] and not latestSI.string1_val):
return (not self.cleaned_data['string2_val'] or not latestSI.string2_val) and self.cleaned_data['string2_val'] != latestSI.string2_val
else:
return True

The inner if/elif/else chains can be replaced with the and-operator and or-operator. This substitution should be almost automatic whenever you see return True and return False for the body of each alternative.
Also, there are multiple references to self.cleaned_data that can be factored-out with:
cleaned = self.cleaned_data

Related

Unable to create a record in except loop of try-except odoo10

When i call the below function through API;
In both try and except conditions I have to keep log in separate table named api.log.
While the function enters in except condition, error occurs on creating record on api.log table
Here is the code:
#http.route('/tax_master',type="json",methodn ['POST'],auth="public",csrf=Falenter code herese)
def create_tax_master(self,**kw):
kw = http.request.params
obj_tax_master = request.env['tax.master']
obj_account_tax = request.env['account.tax']
flag = kw.get('flag')
vals = {}
result = False
if kw.get('name'):
vals['name'] = kw.get('name')
if kw.get('value'):
vals['value'] = kw.get('value')
if kw.get('scope'):
vals['scope'] = kw.get('scope')
if kw.get('is_excise'):
vals['is_excise'] = kw.get('is_excise')
if kw.get('description'):
vals['description'] = kw.get('description')
if kw.get('amount_type'):
vals['amount_type']= kw.get('amount_type')
if 'is_excise' in kw and kw.get('is_excise') not in [1,0]:
result = json.dumps({
"statusCode":02,
"statusDesc":"The value for the field is_excise should be 0 or 1"})
try:
if flag == 'create':
tax_id = obj_tax_master.sudo().create(vals).id
result = json.dumps({"id":tax_id,
"statusCode":01,
"statusDesc":"Successfully Created"
})
elif flag == 'write':
if kw.get('id'):
tax_id_rec = obj_tax_master.sudo().browse([int(kw.get('id'))])
if tax_id_rec.active == False:
result = json.dumps({
'statusCode': 02,
'statusDesc': 'The Tax is Archived.Updation is not possible now',
})
else:
tax_id_rec.sudo().write(vals)
tax_id = kw.get('id')
result = json.dumps({"id":tax_id,
"statusCode":01,
"statusDesc":"Successfully Updated"
})
else:
result = json.dumps({
'statusCode' : 02,
'statusDesc' : 'Please provide valid id to update the record',
})
elif flag == 'delete':
tax_id = obj_tax_master.sudo().browse(int(kw.get('id')))
if tax_id.active == False:
result = json.dumps({
'statusCode': 02,
'statusDesc': 'The record is already archived!!!',
})
else:
tax_id.write({'active':False})
taxes = obj_account_tax.sudo().search([('tax_master_id','=',kw.get('id'))])
for tax in taxes:
tax.write({'active':False})
result = json.dumps({
'statusCode' : 01,
'statusDesc' : 'The record is archived successfully!!!',
})
data = json.loads(result)
self.create_api_log('tax_master', flag, kw, data)
return data
except Exception,e:
result = json.dumps({'statusCode' : 02,'statusDesc' : str(e),})
data = json.loads(result)
self.create_api_log('tax_master', flag, kw, data)
return data
It is solved by using commit function.

How to search values in boto3 python2.7 list dict object - list_tags_for_resource

I have respone object below
response = source.list_tags_for_resource(ResourceName=<ARN>)
taglistk = response['TagList']
print(taglistk)
output :
[{'Value': 'yes', 'Key': 'az'},{'Value': 'dba', 'Key': 'created'},{'Value': 'mariadb', 'Key': 'service'}]
Now I want to write an for if condition to match for only K,V az=yes and service=mariadb and do something
From the tag list of the response, pick a tag by for loop and check the values of given keys, i.e. Key and Value.
response = source.list_tags_for_resource(ResourceName=<ARN>)
for item in response:
if item['Key'] == 'az' and item['Value'] == 'yes':
# do something with item
elif item['Key'] == 'service' and item['Value'] == 'mariadb':
# do otherthing with item
else:
continue

Create Generator from queryset results - Python?

I am new to python I need to convert this following function to the generator to save memory, how can I achieve that?
question = <QuerySet [<Question: foobar?.>]>
for index, question in enumerate(questions):
if question["pk"] == self.pk:
try:
next_question = questions[index + 1]
if next_question["pk"]:
prev_next.update({"next" : next_question["pk"] })
except IndexError:
prev_next.update({"complete" : True })
try:
if index > 0:
previous_question = questions[index - 1]
if previous_question["pk"]:
prev_next.update({"prev" : previous_question["pk"] })
except IndexError:
pass
return prev_next

How to set python variables to true or false?

I want to set a variable in Python to true or false. But the words true and false are interpreted as undefined variables:
#!/usr/bin/python
a = true;
b = true;
if a == b:
print("same");
The error I get:
a = true
NameError: global name 'true' is not defined
What is the python syntax to set a variable true or false?
Python 2.7.3
First to answer your question, you set a variable to true or false by assigning True or False to it:
myFirstVar = True
myOtherVar = False
If you have a condition that is basically like this though:
if <condition>:
var = True
else:
var = False
then it is much easier to simply assign the result of the condition directly:
var = <condition>
In your case:
match_var = a == b
match_var = a==b
that should more than suffice
you cant use a - in a variable name as it thinks that is match (minus) var
match=1
var=2
print match-var #prints -1
Python boolean keywords are True and False, notice the capital letters. So like this:
a = True;
b = True;
match_var = True if a == b else False
print match_var;
When compiled and run, this prints:
True
you have to use capital True and False not true and false
as Poke said:
If you have a condition that is basically like this though:
if <condition>:
var = True
else:
var = False
then it is much easier to simply assign the result of the condition
directly:
var = <condition>
but if you want to reverse it you can use:
var = <condition> is False

Django: How to add an extra form to a formset after it has been constructed?

This is roughly what I'm trying to do:
def post(request):
VehicleFormSet = formset_factory(StaffVehicleForm)
if request.method == 'POST':
vehicle_formset = VehicleFormSet(request.POST)
if 'add_vehicle' in request.POST:
if vehicle_formset.is_valid():
form_count = vehicle_formset.total_form_count()
vehicle_formset.forms.append(vehicle_formset._construct_form(form_count))
Basically, if a user clicks the "Add" button and their entry is valid, I want to add another blank form to the formset, and hide the previous one.
The problem with the code above is that I can't figure out how to increase total_form_count(). The way I have it now, it will work once, and then if you press it again, nothing will happen, presumably because form_count is the same. I also don't like calling _construct_form and relying on the internals.
class RequiredFormSet(BaseFormSet):
def add_form(self, **kwargs):
# add the form
tfc = self.total_form_count()
self.forms.append(self._construct_form(tfc, **kwargs))
self.forms[tfc].is_bound = False
# make data mutable
self.data = self.data.copy()
# increase hidden form counts
total_count_name = '%s-%s' % (self.management_form.prefix, TOTAL_FORM_COUNT)
initial_count_name = '%s-%s' % (self.management_form.prefix, INITIAL_FORM_COUNT)
self.data[total_count_name] = self.management_form.cleaned_data[TOTAL_FORM_COUNT] + 1
self.data[initial_count_name] = self.management_form.cleaned_data[INITIAL_FORM_COUNT] + 1
def add_fields(self, form, index):
super(RequiredFormSet, self).add_fields(form, index)
form.empty_permitted = False
That will do it. Only took 7 hours to figure out. And I still don't know why I need .is_bound = False to make the initial values not screw up.
I do this using javascript. Since the formset renders three management fields
<input type="hidden" id="id_TOTAL_FORMS" value="1" name="TOTAL_FORMS">
<input type="hidden" id="id_INITIAL_FORMS" value="1" name="INITIAL_FORMS">.
<input type="hidden" id="id_MAX_NUM_FORMS" name="MAX_NUM_FORMS">
you can use javascript to increment the id_TOTAL_FORMS value, and just add in the extra fields. So I'd create my fieldset like this:
VehicleFormSet = modelformset_factory(StaffVehicleForm, extra = 0, max_num = None)
The tricky thing is to create the extra form fields in javascript. I usually use AJAX to fetch a new row from a custom view.
For posterity here is another way which works without JS (or alongside JS) and which does not require intimate knowledge of formset methods. Instead, you can just inspect the POST data and adjust it as if JS had done some work client-side. The following makes sure that there is always (at least) one empty form at the end of the formset:
def hsview( request):
HS_formset = formset_factory( HSTestForm, extra=3 )
prefix='XYZZY'
testinpost, empty = 'key', '' # field in the form and its default/empty value
extra=3
# I prefer to do the short init of unbound forms first, so I invert the usual test ...
if request.method != 'POST':
formset = HS_formset( prefix=prefix)
else:
# process POSTed forms data.
# pull all relevant things out of POST data, because POST itself is not mutable
# (it doesn't matter if prefix allows in extraneous items)
data = { k:v for k,v in request.POST.items() if k.startswith(prefix) }
#if there are no spare empty forms, tell it we want another form, in place of or extra to client-side JS
#don't want to crash if unvalidated POST data is nbg so catch all ...
try:
n = int( data[ prefix + '-TOTAL_FORMS'])
test = '{}-{}-{}'.format(prefix, n-1, testinpost)
#print(test)
test = data.get( test, empty)
except Exception:
test = 'bleagh'
# log the error if it matters enough ...
if test != empty:
data[ prefix + '-TOTAL_FORMS'] = n + 1
# now the usual formset processing ...
formset = HS_formset( data, prefix=prefix)
# other_form = OtherForm( request.POST)
if formset.is_valid():
...
I use RegEx in my Vue.js method:
addForm: function () {
this.count++
let form_count = this.count
form_count++
let formID = 'id_form-' + this.count
incremented_form = this.vue_form.replace(/form-\d/g, 'form-' + this.count)
this.formList.push(incremented_form)
this.$nextTick(() => {
let total_forms = document.getElementsByName('form-TOTAL_FORMS').forEach
(function (ele, idx) {
ele.value = form_count
})
})
},
delForm: function () {
if (this.count != 0) {
this.count--
let form_count = this.count
form_count++
let formID = 'id_form-' + this.count
this.formList.pop()
this.$nextTick(() => {
let total_forms = document.getElementsByName('form-TOTAL_FORMS').forEach
(function (ele, idx) {
ele.value = form_count
})
})
}
else return
},