Concurrency Tests in Django - python

Peace be upon all, I just started Django last month. I needed help running concurrency tests in Django, so what I've done is tried to write code that will prevent issues that arise due to lack of concurrency but what I don't know is how to verify and test the code to see that it meets my expectations. What I want is to send multiple requests at the same time to see if the code works as expected.
The target function in views.py
def buy_animal(request):
context = {}
if request.method == 'POST':
form = buys_animal(request.POST)
if form.is_valid() == True or form.is_valid() == False:
#return HttpResponse('asdasd')
nm = request.POST['an_name']
b = Animal.objects.filter(an_name = nm)
#return HttpResponse("yo ")
#nm = request.POST['an_name']
qt = int(request.POST['qty'])
if b.count() <= 0:
return HttpResponse(str(b.count()) + " Sorry we're out of animals")
else:
try:
with transaction.atomic():
b.select_for_update()
b = b[0]
#b.an_name = 'asd'
#b.save()
with transaction.atomic():
Quality.objects.filter( animal = Animal.objects.filter(an_name = 'ringneck')[0] ).select_for_update()
c = Quality.objects.filter( animal = Animal.objects.filter(an_name = 'ringneck')[0] )[0]
c.rating = 'niece'
c.save()
except:
return HttpResponse('Database Error')
if b.qty - qt < 0:
return HttpResponse("Sorry we don't have enough animals")
else:
b.qty = b.qty - qt
b.save()
a = Buy_animal( an_name = nm, qty = qt,
buyer = MyUser.objects.filter(username = request.user.username)[0] )
a.save()
return HttpResponse('animal bought')
else :
form = buys_animal()
context = {}
context = {'form' : form}
return render(request, "buy_animal_form.html", context)
else :
form = buys_animal()
context = {}
context = {'form' : form}
return render(request, "buy_animal_form.html", context)
My models.py code can be found in the below repository
https://bitbucket.org/mab_786/django_models_code/src/master/models.py
`
Kindly ignore any stupid errors on my part as I just started with django.
Thanks in advance. I would really appreciate if someone could share the tests.py code to test such a situation. I didn't write this code as part of any project but to clear up my concepts

Related

Rendering a "<class 'django.template.response.TemplateResponse'>" Object in Django

I have a requirement to incorporate my existing working openstack horizon with our SSO using python-saml.
Hence i referred to demo docs which is written here:
https://github.com/onelogin/python-saml/blob/master/demo-django/demo/views.py#L113
So here as per the guide, I need to render the page as mentioned.
return render(request, 'auth/login.html', {'errors': errors, 'not_auth_warn': not_auth_warn, 'success_slo': success_slo, 'paint_logout': paint_logout, 'SSO': True})
When I am trying the same I am not getting the expected result on page, to be exact, I am not getting the exact desired page with full details. here is the more detail on the same.
Expected page(This is screenshot of page working fine, before i am enabling saml):
Actual page now(Username and password text box not visible, Because login.html file is not enough to render it, because it need form to fully display, using django_auth_views response object "res" is created for the same):
Code:
def login(request, template_name=None, extra_context=None, **kwargs):
"""Logs a user in using the :class:`~openstack_auth.forms.Login` form."""
if not request.is_ajax():.
if (request.user.is_authenticated() and
auth.REDIRECT_FIELD_NAME not in request.GET and
auth.REDIRECT_FIELD_NAME not in request.POST):
return shortcuts.redirect(settings.LOGIN_REDIRECT_URL)
# Get our initial region for the form.
initial = {}
current_region = request.session.get('region_endpoint', None)
requested_region = request.GET.get('region', None)
regions = dict(getattr(settings, "AVAILABLE_REGIONS", []))
if requested_region in regions and requested_region != current_region:
initial.update({'region': requested_region})
if request.method == "POST":
if django.VERSION >= (1, 6):
form = functional.curry(forms.Login)
else:
form = functional.curry(forms.Login, request)
else:
form = functional.curry(forms.Login, initial=initial)
if extra_context is None:
extra_context = {'redirect_field_name': auth.REDIRECT_FIELD_NAME}
if not template_name:
if request.is_ajax():
template_name = 'auth/_login.html'
extra_context['hide'] = True
else:
template_name = 'auth/login.html'
res = django_auth_views.login(request,
template_name=template_name,
authentication_form=form,
extra_context=extra_context,
**kwargs)
# Save the region in the cookie, this is used as the default
# selected region next time the Login form loads.
if request.method == "POST":
utils.set_response_cookie(res, 'login_region',
request.POST.get('region', ''))
req = prepare_django_request(request)
auth = init_saml_auth(req)
errors = []
not_auth_warn = False
success_slo = False
attributes = False
paint_logout = False
if 'sso' in req['get_data']:
return HttpResponseRedirect(auth.login())
elif 'slo' in req['get_data']:
name_id = None
session_index = None
if 'samlNameId' in request.session:
name_id = request.session['samlNameId']
if 'samlSessionIndex' in request.session:
session_index = request.session['samlSessionIndex']
slo_built_url = auth.logout(name_id=name_id, session_index=session_index)
request.session['LogoutRequestID'] = auth.get_last_request_id()
print ('set logout id'+auth.get_last_request_id())
return HttpResponseRedirect(slo_built_url)
if 'samlUserdata' in request.session:
paint_logout = True
if len(request.session['samlUserdata']) > 0:
attributes = request.session['samlUserdata'].items()
return render(request, 'auth/login.html', {'errors': errors, 'not_auth_warn': not_auth_warn, 'success_slo': success_slo, 'paint_logout': paint_logout, 'SSO': True})
Would like to know what may be the problem here, What can be the fix to overcome this issue.
I have given try as below, tried returning the TemplateResponse object which was created in above mentioned code correct working code was just returning 'res' object from code.
return res
hence I tried to return the object instead of html file. ie: 'res' instead of 'auth/login.html'.
return render(request, res, {'errors': errors, 'not_auth_warn': not_auth_warn, 'success_slo': success_slo, 'paint_logout': paint_logout, 'SSO': True})
It returns error as follow:
Getting an error as follows:
ContentNotRenderedError at /auth/login/
The response content must be rendered before it can be accessed.
During analysis, I can see that template object(res), Which is of type: class 'django.template.response.TemplateResponse'
Someone please drop thoughts to figure out how we can resolve.

Django form field update

I have a Django form that lets users choose a tag from multiple tag options. The problem I am facing is that even when the tag list gets updated, the model form does not get the updated tag list from database. As a result, new tags do not appear in options.
Here is my code in forms.py:
class EnglishTagForm(forms.Form):
tag_choices = [(x.tagName, x.tagName.upper()) for x in ClassTag.objects.filter(
agentId=Agent.objects.get(name='English Chowdhury'))]
tag = forms.CharField(widget=forms.Select(choices=tag_choices,
attrs={'class':'form-control'}))
def __init__(self, *args, **kwargs):
super(EnglishTagForm, self).__init__(*args, **kwargs)
self.fields['tag'].choices = [(x.tagName,
x.tagName.upper()) for x in ClassTag.objects.filter(
agentId=Agent.objects.get(name='English Chowdhury'))]
This form is being instantiated in view. My question is what changes should I do so that tag_choices gets updated from database on every instantiation.
How the above form is used in views.py:
```
def complaintDetail(request, complaint_id):
complaint = Complaints.objects.filter(pk=complaint_id).first()
context = {}
if request.method == 'POST':
agent = Agent.objects.get(name="English Chowdhury")
if "SubmitTag" in request.POST:
englishForm = EnglishTagForm(request.POST)
if englishForm.is_valid:
// Complaint Delete Logic
return redirect('chatbot:modComplaints')
else:
englishForm = EnglishTagForm()
context['eForm'] = englishForm
elif "SubmitBundle" in request.POST:
newTagForm = NewTagForm(request.POST)
if newTagForm.is_valid():
// Complaint Delete Logic
complaint.delete()
return redirect('chatbot:modComplaints')
else:
newTagForm = NewTagForm()
context['newForm'] = newTagForm
else:
englishForm = EnglishTagForm()
context['eForm'] = englishForm
newTagForm = NewTagForm()
context['newForm'] = newTagForm
context['complaint'] = complaint
return render(request, 'chatbot/complaintDetail.html', context)
```
Edit: (For future reference)
I decided to modify the tag attribute and convert CharField to ModelChoiceField, which seems to fix the issue.
Updated Class:
class EnglishTagForm(forms.Form):
tag = forms.ModelChoiceField(queryset=ClassTag.objects.filter(
agentId=Agent.objects.get(name='English Chowdhury')),
empty_label=None, widget=forms.Select(
attrs={'class':'form-control'}))
Please remove the list comprehension from Line 2. So that,
tag_choices = [(x.tagName, x.tagName.upper()) for x in ClassTag.objects.filter(
agentId=Agent.objects.get(name='English Chowdhury'))]
becomes
tag_choices = []

How to work with context in Django

I'm trying to create a confirmation page. User can create orders on one page, then the create_order view validates the forms and send a request with context to another view which is called confirm_order. I think that I would work correct but there is one problem. The first time confirm_order gets request and context which contains data from forms. But when User clicks on confirm in this page, the confirm_view is called without this context so I'm getting error:
> ValidationError at /create-job/ [u'ManagementForm data is missing or
> has been tampered with']
Do you guys know how to send the context second time?
Here are those two views:
def create_order(request):
LanguageLevelFormSet = formset_factory(LanguageLevelForm, extra=5, max_num=5)
language_level_formset = LanguageLevelFormSet(request.POST or None)
job_creation_form = JobCreationForm(request.POST or None, request.FILES or None)
context = {'job_creation_form': job_creation_form,
'formset': language_level_formset}
if request.method == 'POST':
if job_creation_form.is_valid() and language_level_formset.is_valid():
cleaned_data_job_creation_form = job_creation_form.cleaned_data
cleaned_data_language_level_formset = language_level_formset.cleaned_data
context = {
'cleaned_data_job_creation_form': cleaned_data_job_creation_form,
"cleaned_data_language_level_formset": cleaned_data_language_level_formset,
}
mutable = request.POST._mutable # I'm adding parameter 'review' to be able to differ between two different posts in confirm_order view
request.POST._mutable = True
request.POST['review'] = True
request.POST._mutable = mutable
return confirm_order(request, context)
else:
return render(request, 'auth/jobs/create-job.html', context=context)
return render(request, 'auth/jobs/create-job.html', context=context)
def confirm_order(request, context):
print context
cleaned_data_job_creation_form = context['cleaned_data_job_creation_form']
cleaned_data_language_level_formset = context['cleaned_data_language_level_formset']
print request.POST['review']
if request.method == 'POST' and request.POST['review'] == True:
file = cleaned_data_job_creation_form['file']
count = 5 #simplified multiple rows
jobs = []
for language_level_form in [d for d in cleaned_data_language_level_formset if d]:
language = language_level_form['language']
level = language_level_form['level']
d = {}
d['language_from'] = cleaned_data_job_creation_form['language_from'].name
d['language_to'] = language
d['number_of_characters'] = count
d['price_per_sign'] = 1
d['estimated_price'] = count * d['price_per_sign']
jobs.append(d)
table = CreatedOrdersTable(jobs)
context = {'table': table,
'cleaned_data_job_creation_form': cleaned_data_job_creation_form,
'cleaned_data_language_level_formset': cleaned_data_language_level_formset}
return render(request, 'auth/jobs/confirm-order.html', context=context)
else:
for language_level_form in [d for d in cleaned_data_language_level_formset if d]:
language = language_level_form['language']
level = language_level_form['level']
Job.objects.create(
customer=request.user,
text_to_translate=cleaned_data_job_creation_form['text_to_translate'],
file=cleaned_data_job_creation_form['file'],
short_description=cleaned_data_job_creation_form['short_description'],
notes=cleaned_data_job_creation_form['notes'],
language_from=cleaned_data_job_creation_form['language_from'],
language_to=language,
level=level,
)
return HttpResponseRedirect('/order-success')
You are returning a template render on your first view. So, the request doesn't end on your confirm_order view.
If you want, you can redirect to reverse('confirm_order') and add the data on session.
In your confirm_order view you will pop the data from session and continue with your flow.

django: passing the form data from one view to another then commit save

i am a beginner and i don't know what i did wrong but here's what it should do
after filling up the fields in form and submitting it, the save_page will send a confirmation code in your email and you will be directed to another template where the valcode will ask for a code that save_page sent.
after submitting, the valcode will then check if your code matches the random generated code that save_page sent and if the code is valid then the data will be saved
here is my views.py
if form.is_valid():
a = (''.join(random.choice(string.ascii_uppercase) for i in range(12)))
i = 1
try:
cde = APPLICANT_DATA.objects.get(code=a)
i = 0
except:
i = 1
while i == 0 :
a = (''.join(random.choice(string.ascii_uppercase) for i in range(12)))
try:
cde = APPLICANT_DATA.objects.get(code=a)
i = 0
except:
i = 1
else:
emails = form.cleaned_data['EMAIL']
mail = EmailMessage('Your activation and application code is: ' + str(a) +", do not show this to anyone", to=[emails])
mail.send()
cde = form.save(commit=False)
return HttpResponseRedirect('verify')
else:
form = application_form()
return render(request, 'frontend/apply.html', {'form': form})
def valcode(request):
sub_form = confirmform(request.POST)
if request.method == 'POST':
if sub_form.is_valid():
e = sub_form.cleaned_data['code']
if e == a:
cde.save()
Any help would be GREATLY appreciated
thanks in advance
I have updated my code, i can't find a tutorial that answers my problem T.T and i also rephrased my question

Decimal value in form wont validate Django

Here's my form i am trying to user to pass two char fields and two coordinates so they can be turned into objects. I just figured out the validation on the char fields, but now the decimal fields wont work. Any suggestions?
from django import forms
class SubmitForm(forms.Form):
title = forms.CharField(max_length=100)
story = forms.CharField(max_length=3000)
lat = forms.DecimalField(max_digits=25, decimal_places=20)
lng = forms.DecimalField(max_digits=25, decimal_places=20)
def clean_title(self):
if len(self.cleaned_data['title']) < 4:
raise forms.ValidationError("Enter your full title")
# Always return the cleaned data
return self.cleaned_data['title']
def clean_story(self):
if len(self.cleaned_data['story']) < 4:
raise forms.ValidationError("Enter your full story")
# Always return the cleaned data
return self.cleaned_data['story']
def clean_lng(self):
if self.cleaned_data['lng'] == 0.0:
raise forms.ValidationError("Enter your full story")
return self.cleaned_data['lng']
def clean_lat(self):
if self.cleaned_data['lat'] == 0.0:
raise forms.ValidationError("Enter your full story")
# Always return the cleaned data
return self.cleaned_data['lat']
def clean(self):
cleaned_data = self.cleaned_data
return cleaned_data
Here's my view
def test(request):
ctxt = {}
if request.method == 'POST':
form = SubmitForm(request.POST) # A form bound to the POST data
if form.is_valid():
lat1 = form.cleaned_data['lat']
lng1 = form.cleaned_data['lng']
# title1 = form.cleaned_data['title']
titlepost = form.cleaned_data['title']
story1 = form.cleaned_data['story']
ctxt = {'titlehere':titlepost}
catid = "test1234"
cat = Category(category=catid)
cat.full_clean()
cat.save()
marker = Marker(lat=lat1, lng=lng1,category=cat, title=titlepost, story=story1)
marker.full_clean()
marker.save()
return render_to_response('home.html', ctxt, context_instance=RequestContext(request))
else:
return render_to_response('test.html', ctxt, context_instance=RequestContext(request))
else:
now = datetime.datetime.now()
form = SubmitForm()
latest_marks = Marker.objects.all().order_by('-submitted')[0:10]
ctxt = {
'marks':latest_marks,
'now':now.date(),
'form': form,
}
return render_to_response('test.html', ctxt, context_instance=RequestContext(request))
For some reason each time i send the form I get this error message
Not really sure what going on. Still pretty new to Django. Any help would be appreciated.
Edit: add in colons I was missing. Error still consists
You're missing some colons after your if statements in the clean methods of your form.
Did you consider using Modelforms ?
You can simplify your code just by using a modelform for Marker model (less code duplication, less code in general to create the model ...)
FYI:
You can send the min_length to CharField and get the len() validation for free :)
class SubmitForm(forms.Form):
title = forms.CharField(max_length=100, min_length=4)
For some reason each time i send the form I get this error message
I can't see the error!
But I tried this and it works ok.
import math
class MyForm(forms.Form):
title = forms.CharField(max_length=100, min_length=4)
story = forms.CharField(max_length=3000, min_length=4)
lat = forms.DecimalField(max_digits=25, decimal_places=20)
lng = forms.DecimalField(max_digits=25, decimal_places=20)
def clean_lat(self):
lat = self.cleaned_data['lat']
if math.ceil(float(lat)) <= 0:
raise forms.ValidationError("Enter your full story")
return self.cleaned_data['lat']
def clean_lng(self):
lng = self.cleaned_data['lng']
if math.ceil(float(lng)) <= 0:
raise forms.ValidationError("Enter your full story")
return self.cleaned_data['lng']

Categories

Resources