form.py
class InvoiceForm(ModelForm,):
def __init__(self,em,first,last):
self.email=em
self.first=first
self.last=last
super(InvoiceForm,self).__init__(self,em,first,last)
self.fields['email']=forms.ChoiceField(choices=[x.email for x in AuthUser.objects.filter(email=em)])
self.fields['first']=forms.ChoiceField(choices=[x.first_name for x in AuthUser.objects.filter(first_name=first)])
self.fields['last']=forms.ChoiceField(choices=[x.last_name for x in AuthUser.objects.filter(last_name=last)])
total_credits_ordered=forms.IntegerField(label=mark_safe('<br/> total_credits_ordered'))
total_mobile_cr_ordered=forms.IntegerField(label=mark_safe('<br/> total_mobile_cr_ordered'))
total_cloud_cr_ordered=forms.IntegerField(label=mark_safe('<br/> total_cloud_cr_ordered'))
invoice_currency=forms.CharField(label=mark_safe('<br/> invoice_currency'),max_length=100)
invoice_currency_code=forms.IntegerField(label=mark_safe('<br/>invoice_currency_code '))
invoice_country=forms.CharField(label=mark_safe('<br/> invoice_country'),max_length=100)
invoice_note=forms.CharField(label=mark_safe('<br/> invoice_note'),max_length=100)
class Meta:
model=Invoices
fields=['total_credits_ordered','total_mobile_cr_ordered','total_cloud_cr_ordered','invoice_currency','invoice_currency_code','invoice_country','invoice_note']
views.py
def test(request):
from app.tests import model_tests
m = model_tests()
print "assf"
try:
if request.method=="POST":
print "sff"
m.create_user_types()
cform=CustomerForm(request.POST)
if cform.is_valid():
em=cform.cleaned_data['email']
username=email
password = cform.cleaned_data['password']
first=cform.cleaned_data['first']
last=cform.cleaned_data['last']
companyname=cform.cleaned_data['company_name']
companyaddr=cform.cleaned_data['company_addr']
companystate=cform.cleaned_data['company_state']
companycountry=cform.cleaned_data['company_country']
id=m.create_customer(username,email,password,first,last,companyname,companyaddr,companystate,companycountry)
print "SFsfg"
iform=InvoiceForm(email,first,last)
print "ggg"
if iform.is_valid():
tco=iform.cleaned_data['total_credits_ordered']
tmco=iform.cleaned_data['total_mobile_cr_ordered']
tcco=iform.cleaned_data['total_cloud_cr_ordered']
ic=iform.cleaned_data['invoice_currency']
icc=iform.cleaned_data['invoice_currency_code']
c=iform.cleaned_data['invoice_country']
inote=iform.cleaned_data['invoice_note']
id_i=m.create_invoices(id,tco,tmco,tcco,ic,icc,c,inote)
pform=PaymentForm()
print "dsf"
pform=PaymentForm(request.POST)
if pform.is_valid():
tpm=pform.cleaned_data['total_payment_made']
ps=pform.cleaned_data['payment_status']
pt=pform.cleaned_data['payment_type']
m.create_payment(id_i,tpm,ps,pt)
return HttpResponse("test successful")
else:
print "d"
cform=CustomerForm()
iform=InvoiceForm()
pform=PaymentForm()
return render(request, 'test.html', {'cform': cform,'iform':iform,'pform':pform})
except Exception as e:
return HttpResponse("Exception : %s" %(e))
return HttpResponse("Tests Successfull...")
It is showing:
Exception : __init__() takes exactly 4 arguments (1 given)
but I have passed parameters to the form.
We don't have the stacktrace in the question but problem is probably here:
else:
print "d"
cform=CustomerForm()
iform=InvoiceForm()
pform=PaymentForm()
Here you are creating objects without passing any parameters. Since the instance itself is always passed, the message says that it misses the other parameters which are em,first,last
I suggest that you remove everything after the else part since it does nothing useful or a warning like this to avoid silent errors:
else:
print("Unsupported method "+request.method)
Related
I have 3 fields that I want to compare salary "from" field and "to" field and also there is fixed salary field. I have no idea how to do it, since there is no documentation how to do it, so i created custom function that look to each other and trying to se if they have a value.
def validate_salarylow(self, salarylow):
if self.validate_salary_fixed(self.salary_fixed) != "":
salarylow.data = int(0)
else:
try:
salarylow.data = int(salarylow.data)
except:
raise ValidationError("value is not a number")
return salarylow.data
def validate_salary_high(self, salary_high):
if self.validate_salary_fixed(self.salary_fixed) != "":
salary_high.data = int(0)
else:
try:
salary_high.data = int(salary_high.data)
except:
raise ValidationError("value is not a number")
return salary_high.data
def validate_salary_fixed(self, salary_fixed):
if self.validate_salary_high(self.salary_high) != "":
salary_fixed.data = int(0)
try:
salary_fixed.data = int(salary_fixed.data)
except:
raise ValidationError("value is not a number")
return salary_fixed.data
if I don't set if self.validate_salary_high(self.salary_high) != "": everything works fine. but when i set it I'm getting "RecursionError: maximum recursion depth exceeded" error.validate_salary_fixed function looks to validate_salary_high function and vice versa. I'm new in Python and flask and I'm sure there is easy solution, but I cant find it so I would appreciate if anyone could help.
My suggestion is to suppress the error message of the integer field by overwriting it. Thus, the types of the inputs do not have to be converted.
For validation I use two custom validators, one of which checks whether a range or a fixed value has been entered and the second checks the range for its limits. In addition, pre-built validators are used to prohibit negative values.
I'm not sure if you really need the field for the fixed salary, because it is possible to define a fixed value by narrowing the range.
from flask_wtf import FlaskForm
from wtforms import IntegerField
from wtforms.validators import (
NumberRange,
Optional,
StopValidation,
ValidationError
)
class OptionalIntegerField(IntegerField):
def process_data(self, value):
try:
super().process_data(value)
except ValueError:
pass
def process_formdata(self, valuelist):
try:
super().process_formdata(valuelist)
except ValueError:
pass
def validate_salary(form, field):
range_fields = [form.salary_low, form.salary_high]
if all(f.data is None for f in [form.salary_low, form.salary_high, form.salary_fixed]) or \
(form.salary_fixed.data is not None and any(f.data is not None for f in range_fields)) or \
(form.salary_fixed.data is None and any(f.data is None for f in range_fields)):
raise StopValidation('Either state a range from low to high or a fixed salary.')
def validate_salary_range(form, field):
if form.salary_low.data and form.salary_high.data and \
form.salary_low.data > form.salary_high.data:
raise ValidationError('The lower value should be less than or equal to the higher one.')
class SalaryForm(FlaskForm):
salary_low = OptionalIntegerField(
validators=[
validate_salary,
validate_salary_range,
Optional(),
NumberRange(min=0)
]
)
salary_high = OptionalIntegerField(
validators=[
validate_salary,
validate_salary_range,
Optional(),
NumberRange(min=0)
]
)
salary_fixed = OptionalIntegerField(
validators=[
validate_salary,
Optional(),
NumberRange(min=0)
]
)
app = Flask(__name__)
app.secret_key = 'your secret here'
#app.route('/', methods=['GET', 'POST'])
def index():
form = SalaryForm(request.form)
if form.validate_on_submit():
print(form.salary_low.data, ' - ', form.salary_high.data, '||', form.salary_fixed.data)
return render_template('index.html', **locals())
Let's take a look at your code:
Your function validate_salary_high calls validate_salary_fixed.
But when you go to your function validate_salary_fixed it calls validate_salary_high.
So you go back to your function validate_salary_high which calls validate_salary_fixed.
Now in your function validate_salary_fixed, you call validate_salary_high.
Your functions repeatedly call each other over and over again, forever, until your computer eventually throws an error - and this is exactly what is happening to you.
The way to get around this is to remove one of your recursive calls. More specifically you should either
remove your call to validate_salary_fixed in the function validate_salary_high
or remove your call to validate_salary_high in the function validate_salary_fixed
You should chose which function call to remove depending on the goal of your code (which I don't fully understand.) Good luck!
I am a beginner in Python and I need some help on decorators. I am writing a few methods which call other methods that are generated using swagger. Basically all these swagger methods have GET APIs. All I need to do in my code is to call those swagger methods and return the value. I am looking for ways to optimize this instead of writing the same kind of method for each API. I came across decorators which can be used in this case. But my implementation is not giving the desired result
def get_component_info(self, func):
def inner():
data = None
try:
ret = func()
if ret.status == 200:
log.info('ret ' + str(ret))
else:
logging.error('Error: ' + str(ret.text))
except Exception as e:
logging.error(" failed with error " + str(e.reason) +
" and error code " + str(e.status))
finally:
return data
return inner()
def get_firewall_info(self):
return self._monitor.list_firewall_monitors_with_http_info() <-- swagger method
def get_firewall_info_caller(self):
get_firewall_info = self.get_component_info(self.get_firewall_info())
But the above implementation always return None because it never executes self._monitor.list_firewall_monitors_with_http_info(), but the test isn't failing
If you help me fix this, then I can use the same for getting server info, auth info, network info, etc. If decorators can't be used, what else I can use to optimize this..?
Thanks
Decorators are usually functions which take a second function as an argument and then define and return a third function which calls the second function while changing its input and/or output. It looks like you have a better handle on this than I did as a beginner.
def decorator(func):
def inner(*args, **kwargs):
# Do stuff here...
value = func(*args, **kwargs)
# ...or here.
return value
return inner
The only change I would recommend to your decorator is not to call inner and return the result, but to return the function itself. When you make this change you'll have to call the function you are returning now after it is returned.
def get_component_info(self, func):
def inner():
# ...
return inner
def get_firewall_info_caller(self):
# You will now want to call the `inner` function after you get
# it from `get_component_info`.
get_firewall_info = self.get_component_info(...)()
It looks like the core of your bug is that you aren't providing a function to get_component_info; you're providing the result of calling that function. I think that changing the code to not call get_firewall_info should fix your code.
def get_firewall_info_caller(self):
# You don't want to call the function you're providing to a
# decorator, since it's expecting the function not the result.
get_firewall_info = self.get_component_info(self.get_firewall_info)()
I resolved it as shown below. Not sure if it is the right approach. Please correct me
def get_component_info(self, func):
def inner():
data = None
try:
ret = func()
if ret.status == 200:
log.info('ret ' + str(ret))
else:
logging.error('Error: ' + str(ret.text))
except Exception as e:
logging.error(" failed with error " + str(e.reason) +
" and error code " + str(e.status))
finally:
return data
return inner
def get_firewall_info(self):
data = self.get_component_info(self._monitor.list_firewall_monitors_with_http_info)()
return data
I'm new to python but I know that self is automatically passed.I'm unable to understand why am I getting this error and I get the same error with getGraph function as well 2 required 1 given.
What is going wrong here?
CreateDoc is in CeleryTasks.py and insert_manager in MongoTriggers.py
#app.task
def createDoc(self):
print ("CeleryTasks:CreateDoc")
if 'refs' not in self.data:
return
print(self.data['refs'])
for id in self.data['refs']:
doc = self.db[self.collName].find_one({'_id': id})
if doc is None:
insertedID = self.db[self.collName].insert_one({
"_id": id
})
print (insertedID)
#Trigger on Mongo Operations
def insert_manager(op_document):
print("Data Inserted")
# pprint.pprint (op_document)
data = op_document['o']
ns = op_document['ns'].split('.')
# pprint.pprint (data)
docID = op_document['o']['_id']
tasks = CeleryTasks(port, docID, dbName, collectionName, data)
tasks.createDoc()
tasks.getGraph.delay(docID)
self is always passed when it's method of class.
Celery tasks are independent functions. You can add them self arguments by adding bind=True via the app decorator but it is used for a different purpose: bounded tasks
this funstion works well :
def create_layer(layers_list,position=0,layer_obj=None):
if not layer_obj:
layer_obj,created = Layer.objects.get_or_create(name=layers_list[0])
return create_layer(layers_list,position,layer_obj)
else:
position +=1
if position < len(layers_list) :
obj,created = Layer.objects.get_or_create(name=layers_list[position],parent=layer_obj)
return create_layer(layers_list,position,obj)
else:
return layer_obj
But when I put it into class, I got error :
create_layer() takes at most 4 arguments (5 given)
class Test():
def test1(self):
self.create_layer(layers_list)
def create_layer(self,layers_list,position=0,layer_obj=None):
if not layer_obj:
layer_obj,created = Layer.objects.get_or_create(name=layers_list[0])
return self.create_layer(self,layers_list,position,layer_obj)
else:
position +=1
if position < len(layers_list) :
obj,created = Layer.objects.get_or_create(name=layers_list[position],parent=layer_obj)
return self.create_layer(self,layers_list,position,obj)
else:
return layer_obj
What happened??
How can I fix it ??
Don't pass self to self.create_layer when calling it recursively. This is done for you by Python when it calls a method of a class instance. What happens here is that Python adds another self to the front of your argument list, thereby making it one argument too many.
I'm calling a method using reverse but I have problem argument that I am not able to understand.
My error :
Reverse for 'shopping.views.payment_confirmation' with arguments '(35,)' and keyword arguments '{}' not found.
My url:
url(r'^payment_confirmation/(?P<id>\d+\d{2\})/$', 'payment_confirmation', name='payment_confirmation'),
My view:
def show(request):
...
...
payment.submit(settings.SITE_URL + reverse("shopping.views.payment_confirmation", args=[payment.id]))
My model Payment:
class Payment(models.Model):
...
...
def submit(self, redirect_url):
'''
Sends self as a Payment through PagSeguro API.
Payment instance MUST BE SAVED before calling this method.
'''
if not self.id:
#Temporary to identify which problem caused the crash.
raise ValidationError
#creating a reference if its None
if self.reference is None:
self.reference = configs.PAGSEGURO_REFERENCE_PREFIX + str(self.id)
document = Document()
document.appendChild(self.to_element(document, redirect_url))
response = document2dict(api.submit_payment(document))
try:
self.code = response['checkout']['code']
self.answered_on = datetime.datetime.now()
self.save()
except:
error_str = ""
if type(response["errors"]["error"]) != list:
response["errors"]["error"] = [response["errors"]["error"]]
for error in response["errors"]["error"]:
error_payment = ErrorPayment()
error_payment.code = int(error['code'])
error_payment.payment = self
error_payment.save()
error_str += "[%s: %s]" % (error_payment.code,
error_payment.get_code_display())
raise Exception(error_str)
the error is here payment.submit (settings.SITE_URL + reverse ("shopping.views.payment_confirmation", args = [payment.id]))
I', using this api https://bitbucket.org/leonardosantos/django-pagseguro2/
This line: reverse("shopping.views.payment_confirmation", args=[payment.id]) tells Django to find a url that matches a method called payment_confirmation in the views.py file in the shopping app that will accept a payment ID parameter.
In the error that you shared, the payment.id was 35. The error is saying that either there is no method called payment_confirmation in your shopping.views or the method does not accept a single int as a parameter.
You didn't share a payment_confirmation method in your views file so it seems that that is the issue. You need to add:
def payment_confirmation(payment_id):
#do stuff
to your views.