I have the following form in my flask app. I'd like to ensure that the input value is actually an integer and also if the value entered in token > k here k can be some number it spits an error message to the screen. The IntegerField doesn't seem to enforce integer values, e.g., if the user enters 2.3 it passes that to my function which fails because it expects an integer.
Can this type of error message happen in the form or do I need to program that inside my flask app once the value is passed from the form to the server?
class Form(FlaskForm):
token = IntegerField('Token Size', [DataRequired()], default = 2)
submit = SubmitField('Submit')
EDIT
Per the comment below, updating this with my revised Form and the route
class Form(FlaskForm):
token = IntegerField('Token Size', validators=[DataRequired(), NumberRange(min=1, max=10, message='Something')], default = 2)
ngram_method = SelectField('Method', [DataRequired()],
choices=[('sliding', 'Sliding Window Method'),
('adjacent', 'Adjacent Text Method')])
rem_stop = BooleanField('Remove Stop Words', render_kw={'checked': True})
rem_punc = BooleanField('Remove Punctuation', default = True)
text2use = SelectField('Text To Use for Word Tree', [DataRequired()],
choices=[('clean', 'Clean/Processed Text'),
('original', 'Original Text String')])
pivot_word = TextField('Pivot Word for Word Tree', [DataRequired()])
submit = SubmitField('Submit')
And the route in which the form is used
#word_analyzer.route('/text', methods=('GET', 'POST'))
def text_analysis():
form = Form()
result = '<table></table>'
ngrams = '<table></table>'
orig_text = '<table></table>'
text = ""
if request.method == 'POST':
tmp_filename = tempfile.gettempdir()+'\\input.txt'
if request.files:
txt_upload = request.files.get('text_file')
if txt_upload:
f = request.files['text_file']
f.save(tmp_filename)
if os.path.exists(tmp_filename):
file = open(tmp_filename, 'r', encoding="utf8")
theText = [line.rstrip('\n') for line in file]
theText = str(theText)
token_size = form.token.data
stops = form.rem_stop.data
punc = form.rem_punc.data
ngram_method = form.ngram_method.data
text_result = text_analyzer(theText, token_size = token_size, remove_stop = stops, remove_punctuation = punc, method = ngram_method)
result = pd.DataFrame.from_dict(text_result, orient='index', columns = ['Results'])[:-3].to_html(classes='table table-striped table-hover', header = "true", justify = "center")
ngrams = pd.DataFrame.from_dict(text_result['ngrams'], orient='index', columns = ['Frequency']).to_html(classes='table table-striped table-hover', header = "true", justify = "center")
if form.pivot_word.data == None:
top_word = json.dumps(text_result['Top Word'])
else:
top_word = json.dumps(form.pivot_word.data)
if form.text2use.data == 'original':
text = json.dumps(text_result['original_text'])
else:
text = json.dumps(text_result['clean_text'])
if form.validate_on_submit():
return render_template('text.html', results = [result], ngrams = [ngrams], form = form, text=text, top_word = top_word)
return render_template('text.html', form = form, results = [result],ngrams = [ngrams], text=text, top_word='')
Use the NumberRange validator from wtforms.validators.NumberRange. You can pass an optional Min and Max value along with the error message. More info here
Update
# Form Class
class Form(FlaskForm):
token = FloatField('Token Size', validators=[DataRequired(), NumberRange(min=1, max=10, message='Something')])
# Route
if form.validate_on_submit():
print(form.name.data)
Here is an example that should work, make sure your form class field looks similar and also that in your route you use form.validate_on_submit():.
Related
Context:
I click on a button -> a WindowDialogue appears -> there are 2 LineEdit Nodes and a button
Supposed procedure:
I fill these LineEdits, press the button, and the function tied to the button receives the texts from the LineEdits (and creates a dictionary key-value pair).
Problem:
The texts from the LineEdits do not pass down to the function (through connect()).
I tried passing the text directly with LineEdit.text. I tried writing it in a different variable and passing the variable. The debug shows the function is getting executed (no problem with that), but the strings passed from the LineEdits are always empty. Somehow, it worked for some time when I explicitly pressed ENTER after filling the LineEdits. But after I tried to fix the aforementioned problem, it stopped working altogether.
P.S. Everything I mentioned is created dynamically through the code, if that matters.
Code:
#Declaring the variables
var temp_text_key = ""
var temp_text_value = ""
#Function to show up a dialogue window with LineEdits and Confirm button
func _on_add_new_property(dict: Dictionary):
temporal_window_dialogue = WindowDialog.new()
temporal_window_dialogue.rect_min_size = Vector2(410,90)
temporal_window_dialogue.resizable = true
temporal_window_dialogue.popup_exclusive = true
temporal_window_dialogue.window_title = "Adding new property to %s" % get_dict_name_by_id(professions, dict["id"])
var le_key = LineEdit.new()
le_key.placeholder_text = "Name of the property"
le_key.hint_tooltip = "Name of the property"
le_key.connect("text_changed", self, "_on_add_new_prop_text_entered", ["key"])
var le_value = LineEdit.new()
le_value.expand_to_text_length = true
le_value.placeholder_text = "Value of the property"
le_value.set("custom_constants/minimum_spaces", 36)
le_value.hint_tooltip = "Value of the property"
le_value.connect("text_changed", self, "_on_add_new_prop_text_entered", ["value"])
var lab = Label.new()
lab.text = "Should the Value become a Dictionary?"
var check_bt = CheckBox.new()
var vbox = VBoxContainer.new()
var grid_container = GridContainer.new()
grid_container.columns = 2
var accept_bt = Button.new()
accept_bt.text = "Confirm"
temporal_window_dialogue.add_child(vbox)
vbox.add_child(grid_container)
grid_container.add_child(le_key)
grid_container.add_child(le_value)
grid_container.add_child(lab)
grid_container.add_child(check_bt)
vbox.add_child(accept_bt)
grid_container.set("custom_constants/vseparation", 5)
grid_container.set("custom_constants/hseparation", 5)
check_bt.connect("pressed", self, "_on_check_dict_pressed")
popup_window.add_child(temporal_window_dialogue)
temporal_window_dialogue.connect("popup_hide", self, "_on_close_specific_codegenerated_popup", [temporal_window_dialogue])
temporal_window_dialogue.popup_centered()
accept_bt.connect("pressed", self, "_on_add_new_property_confirmation", [dict, temp_text_key, temp_text_value])
#Function to create a new key/value pair in a dictionary
func _on_add_new_property_confirmation(dict: Dictionary, prop_name: String, prop_value: String):
if prop_name == "" or prop_value == "":
send_message_to_console("Neither of the two can be empty", 3)
return
if add_dictionary_flag:
dict[prop_name] = {
prop_value: {
"id": get_free_local_id_for_dict(dict)
}
}
elif !add_dictionary_flag:
if keywords_for_dictionaries.has(prop_name):
send_message_to_console("Only Dictionary items can become %s" % prop_name)
dict[prop_name] = prop_value
temp_text_key = ""
temp_text_value = ""
#Optional function to write the text from LineEdits to the variables
func _on_add_new_prop_text_entered(new_text, key_or_value):
if key_or_value == "key":
temp_text_key = new_text
elif key_or_value == "value":
temp_text_value = new_text
You mentioned using 'LineEdit.text', but have you tried the following?
var text = LineEdit.get_text()
If this doesn't help, please update your original post to include code examples.
I am trying to update a handful of fields if the record has been marked as deleted. When I debug, I can see that the values are being assigned in the view, but not being updated in the DB. I'm not sure what I'm missing.
views.py
contact_formset = ContactFormSet(request.POST, prefix='contact')
for contact in contact_formset.deleted_forms:
contact = contact.cleaned_data
print(contact)
instance = contact['id_cnt']
contact_id = instance.id_cnt
contact_object = get_object_or_404(AppContactCnt, id_cnt=contact_id)
contact_object.deleted_cnt = True
contact_object.date_deleted_cnt = '2020-11-23'
contact_object.deleted_by_cnt = 'adeacon'
contact_object.save()
Included the delete code with the edit code. Seemed to do the trick:
if '_edit_contact_formset' in request.POST:
contact_formset = ContactFormSet(request.POST, prefix='contact')
for contact_form in contact_formset:
if contact_form.is_valid() and contact_form.has_changed():
contact_data = contact_form.cleaned_data
# print(contact_data)
customer_obj = get_object_or_404(AppCustomerCst, id_cst=id)
contact_form.instance.idcst_cnt = customer_obj
contact_form.instance.idtrp_cnt = '-1'
if contact_data['DELETE'] is True:
print('delete me')
contact_form.instance.deleted_cnt = True
contact_form.instance.date_deleted_cnt = '2020-11-23'
contact_form.instance.deleted_by_cnt = 'adeacon'
messages.info(request, 'Contact deleted successfully')
contact_form.save()
formset = ContactFormSet(
queryset=AppContactCnt.objects.filter(idcst_cnt=id).exclude(deleted_cnt=True).select_related('idctp_cnt'),
prefix='contact')
if contact_data['DELETE'] is not True:
messages.info(request, 'Contacts updated successfully!')
I want to add xml to my .docx document using python-docx library. I tried this code from stackoverflow but it doesn't work, I don't know why. I get nothing when opening the docx with LibreOffice and Microsoft word.
table = document.add_table(rows=1, cols=1)
p = table.cell(0, 0).paragraphs[0]
run = p.add_run()
tag = run._r
start = docx.oxml.shared.OxmlElement('w:bookmarkStart')
start.set(docx.oxml.ns.qn('w:id'), '0')
start.set(docx.oxml.ns.qn('w:name'), '0')
tag.append(start)
ctype = docx.oxml.OxmlElement('w:complexType')
ctype.set(docx.oxml.ns.qn('w:name'), 'CT_FFCheckBox')
seq = docx.oxml.OxmlElement('w:sequence')
choice = docx.oxml.OxmlElement('w:choice')
el = docx.oxml.OxmlElement('w:element')
el.set(docx.oxml.ns.qn('w:name'), 'size')
el.set(docx.oxml.ns.qn('w:type'), 'CT_HpsMeasure')
el2 = docx.oxml.OxmlElement('w:element')
el2.set(docx.oxml.ns.qn('w:name'), 'sizeAuto')
el2.set(docx.oxml.ns.qn('w:type'), 'CT_OnOff')
choice.append(el)
choice.append(el2)
el3 = docx.oxml.OxmlElement('w:element')
el3.set(docx.oxml.ns.qn('w:name'), 'default')
el3.set(docx.oxml.ns.qn('w:type'), 'CT_OnOff')
el3.set(docx.oxml.ns.qn('w:minOccurs'), '0')
el4 = docx.oxml.OxmlElement('w:element')
el4.set(docx.oxml.ns.qn('w:name'), 'checked')
el4.set(docx.oxml.ns.qn('w:type'), 'CT_OnOff')
el4.set(docx.oxml.ns.qn('w:minOccurs'), '0')
seq.append(choice)
seq.append(el3)
seq.append(el4)
ctype.append(seq)
start.append(ctype)
end = docx.oxml.shared.OxmlElement('w:bookmarkEnd')
end.set(docx.oxml.ns.qn('w:id'), '0')
end.set(docx.oxml.ns.qn('w:name'), '0')
tag.append(end)
Can you help me? Thank you very much
PS : I find the code here
Tweaking the function from this SO post, I got this to work.
import docx
import random
def addCheckbox(para, box_id, name):
run = para.add_run()
tag = run._r
fld = docx.oxml.shared.OxmlElement('w:fldChar')
fld.set(docx.oxml.ns.qn('w:fldCharType'), 'begin')
ffData = docx.oxml.shared.OxmlElement('w:ffData')
e = docx.oxml.shared.OxmlElement('w:name')
e.set(docx.oxml.ns.qn('w:val'), 'Check1')
ffData.append(e)
ffData.append(docx.oxml.shared.OxmlElement('w:enabled'))
e = docx.oxml.shared.OxmlElement('w:calcOnExit')
e.set(docx.oxml.ns.qn('w:val'), '0')
ffData.append(e)
e = docx.oxml.shared.OxmlElement('w:checkBox')
e.append(docx.oxml.shared.OxmlElement('w:sizeAuto'))
ee = docx.oxml.shared.OxmlElement('w:default')
ee.set(docx.oxml.ns.qn('w:val'), '0')
e.append(ee)
ffData.append(e)
fld.append(ffData)
tag.append(fld)
run2 = para.add_run()
tag2 = run2._r
start = docx.oxml.shared.OxmlElement('w:bookmarkStart')
start.set(docx.oxml.ns.qn('w:id'), str(box_id))
start.set(docx.oxml.ns.qn('w:name'), name)
tag2.append(start)
run3 = para.add_run()
tag3 = run3._r
instr = docx.oxml.OxmlElement('w:instrText')
instr.text = 'FORMCHECKBOX'
tag3.append(instr)
run4 = para.add_run()
tag4 = run4._r
fld2 = docx.oxml.shared.OxmlElement('w:fldChar')
fld2.set(docx.oxml.ns.qn('w:fldCharType'), 'end')
tag4.append(fld2)
run5 = para.add_run()
tag5 = run5._r
end = docx.oxml.shared.OxmlElement('w:bookmarkEnd')
end.set(docx.oxml.ns.qn('w:id'), str(box_id))
end.set(docx.oxml.ns.qn('w:name'), name)
tag5.append(end)
if __name__ == '__main__':
document = docx.Document()
document.add_heading('Document Title', 0)
p1 = document.add_paragraph('A paragraph with a checkbox ')
addCheckbox(p1, random.randint(16*1024, 32*1024), 'justinwashere')
document.save('demo.docx')
I changed the contents of his ffData in the function to match the replacement XML in his original question.
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
Trying to POST through REST-API, some JSON object, but having some issue and getting the error TypeError: Object of type set is not JSON serializable
Getting error when trying to post the agentResource_info to a REST-API
def agentresource(self):
global fogarea_info
while self.deviceID_cimiresource is None:
time.sleep(0.1)
deviceID = self.userID
dID = str(deviceID)
# devID = {"device": dID}
MyleaderID = {str(self.deviceID_cimiresource)}
while self._running:
dynamic = dynamic_info()
devdyna = json.loads(dynamic)
devwifiip = devdyna['wifiAddress']
devethip = devdyna['ethernetAddress']
devips = [*devethip, *devwifiip]
devIP = str(', '.join(devips))
devip = str(devIP)
r2 = requests.get("http://cimi:8201/api/device-dynamic",headers={"slipstream-authn-info": "internal ADMIN"}, verify=False)
dynamics_info = r2.json()
rs_info = dynamics_info['deviceDynamics']
ips1 = [item['wifiAddress'] for item in rs_info]
ips2 = [item['ethernetAddress'] for item in rs_info]
ips3 = [*ips1, *ips2]
childips = str(ips3)
backupip = 'None'
authenticated = True
connect = True
isleader = True
agentResource_info = json.dumps({"device_id": MyleaderID, "device_ip": devip, "leader_id": dID, "leader_ip": devip, "authenticated": authenticated, "connected": connect, "isLeader": isleader, "backup_ip": backupip, "childrenIPs": childips})
#print("I'm here can you see me!!!!")
#agentRes_info = json.dumps(agentResource_info)
#print(agentResource_info)
try:
if self.count is 0:
r1 = requests.post("http://cimi:8201/api/agent-resource",headers={"slipstream-authn-info": "internal ADMIN"},json=agentRes_info, verify=False)
print('r1', r1, r1.request, r1.reason, r1.json())
self.count = r1.json()['count']
else:
r1 = requests.put("http://cimi:8201/api/agent-resource",headers={"slipstream-authn-info": "internal ADMIN"},json=agentRes_info, verify=False)
print('r1', r1, r1.request, r1.reason, r1.json())
except ConnectionError as e:
print(e)
r1 = "No response"
print(r1)
time.sleep(60)
You wrote:
MyleaderID = {str(self.deviceID_cimiresource)}
and snakecharmerb points out that set
won't serialize as it isn't a native JSON type.
Better to assign a str instead.
Also, pep-8 asks that you use lowercase snake_case
for such variable names: my_leader_id