I want to write test for my code and pass a value to a form how can i do that? I have two form in my code and this value should pass just to one of them.
my unittest:
def test_user_has_project(self):
resp = self.client.post('/register/', NEW_USER)
self.assertRedirects(resp, '/register/confirm/')
confirmation_code = self.client.session['confirm_code']
resp = self.client.post('/register/confirm/',
{'confirm_code':confirmation_code})
but this code pass confirmation code to both forms.
my views:
if request.method == 'POST':
form = forms.RegistrationConfirmForm(request.POST)
if (form.is_valid() and
form.cleaned_data['confirm_code'] == request.session['confirm_code']):
# Register the user in the backend
form = forms.RegistrationForm(request.session['registering_user'])
sorry. I'm a beginner in both coding and asking question!
Related
I'm new to Django's testing and trying to write test functions for views, but I don't get the whole test view thing, I've seen a lot of examples but it seems to be to difficult, I need an example on something I wrote to get the idea.
here's a function I want to test its post and get:
def ForgetPasswordRegistry(self, request):
forgetpassword = True
if request.method == 'GET':
if 'UserID' in request.session:
forgetpassword = False
return request, forgetpassword
elif request.method == 'POST':
email = request.POST['email']
if self.IsUserExist(email):
forget = models.ForgetPasswordRegistry()
forget.UserID = self.GetUser(email)
forget.Access = 1
session = random.randint(999999999999999, 9999999999999999999999999999999999)
forget.Session = str(session)
link = 'http://127.0.0.1:8000/home/resetpassword/' + forget.Session
self.SendEmail('Reset-Password', link, [forget.UserID.Email])
forget.save()
FeedBack = ' Check Your Mail You Got A Recovery Mail'
AlertType = 'alert-success'
return request, AlertType, None, FeedBack, None, None
else:
AlertType = 'alert-danger'
ModalFeedBack = 'This Email Dose Not Exist'
EmailErrors = 'This Email Dose Not Exist'
return request, AlertType, forgetpassword, None, EmailErrors, ModalFeedBack
Don't let the concept of views confuse you!! Essentially there is a python function that you need to exercise certain conditionals of.
It looks like there are 4 main branches:
GET not in session
GET in session
POST exists
POST does not exist
so there should probably be at least 4 different tests. I'll post the first one because it is pretty straightforward:
def ForgetPasswordRegistry(self, request):
forgetpassword = True
if request.method == 'GET':
if 'UserID' in request.session:
forgetpassword = False
return request, forgetpassword
def test_forget_get_user_id_in_session(self):
request = Mock(session={'UserID': 'here'}, method='GET')
# instantiate your view class
yourview = YourView()
sefl.assertEqual(yourview.ForgetPasswordRegistry(request), (request, False))
The post user exists branch is a little more complicated because there are more things that the test needs to account for, and potentially provide stub implementations for:
SendEmail
GetUser
models.ForgetPasswordRegistry()
Use Django's test client: https://docs.djangoproject.com/en/stable/topics/testing/tools/#the-test-client
Example:
from django.test import Client, TestCase
class ViewTestCase(TestCase):
def test_post_creation(self):
c = Client() # instantiate the Django test client
response = c.get('/forgetpassword/')
self.assertEqual(response.status, 200)
I'm struggling to understand how to submit data from two django forms into two separate database tables from the same view. I only want one submit button. While this question got me closer to the solution, I'm getting errors and the data is not writing to the database. I think this code actually checks the two forms against each other instead of submitting both forms in one go. Any ideas?
Here's what I've tried:
For one form --> one table. This works, so it's a start.
# views.py
def BookFormView(request):
if request.method == 'POST':
form = BookForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect("/books/")
else:
form = BookForm()
return render(request, 'books/createbooks.html',
{'form' : form})
However, when I add this form in from forms.py to get the subsequent views.py I get local variable 'book_form' referenced before assignment. That's usually an easy global-vs-local variable issue to fix, but I don't know what it means in this case.
def BookFormView(request):
if request.method == 'POST':
if 'book' in request.POST:
book_form = BookForm(request.POST, prefix='book')
if book_form.is_valid():
book_form.save()
return HttpResponseRedirect("/books/")
bookdetailsform = BookDetailsForm(prefix='bookdetails')
elif 'bookdetails' in request.POST:
bookdetailsform = BookDetailsForm(request.POST, prefix='bookdetails')
if bookdetailsform.is_valid():
bookdetailsform.save()
return HttpResponseRedirect("/books/")
book_form = BookForm(prefix='book')
else:
book_form = BookForm(prefix='book')
bookdetailsform = BookDetailsForm(prefix='bookdetails')
return render(request, 'books/createbook.html',
{'book_form' : book_form,
'bookdetailsform': bookdetailsform})
Based on the question's comments:
def BookFormView(request):
if request.method == 'POST':
book_form = BookForm(request.POST, prefix='book')
bookdetailsform = BookDetailsForm(request.POST, prefix='bookdetails')
if book_form.is_valid() and bookdetailsform.is_valid():
book_form.save()
bookdetailsform.save()
return HttpResponseRedirect("/books/")
else:
book_form = BookForm(prefix='book')
bookdetailsform = BookDetailsForm(prefix='bookdetails')
return render(request, 'books/createbook.html',
{'book_form': book_form, 'bookdetailsform': bookdetailsform})
I think the problem is that when a user submits a bookdetails post request,
it will be handled under if 'book' in request.POST: condition. Why?
because string bookdetails contains string book, no matter the type of request they do, it will be handled with if book in request.POST: condition.
I believe fixing that if condition problem is the first step.
I am working on my first django webaite, I am trying to submit two forms one after the other.
Here is the views.py :
def home(request):
import json
if request.method == 'POST':
form = MajorForm(request.POST)
if form.is_valid():
url = 'http://www.mysite.com:8082'
dataout = {'my':'data'}
headers = {'content-type':'application/json'}
r = requests.post(url,data=json.dumps(dataout),headers=headers)
return collector(request)
else:
return HttpResponse("thnx")
else:
form = MajorForm()
return render(request,'index.html',{'form':form})
def collector(request):
if request.method == 'POST':
form = ContactForm(request.POST)
if form.is_valid():
return HttpResponse("thanx")
else:
return HttpResponse("not valid")
else:
form = ContactForm();
return render(request,'collector.html',{'form':form})
So the first view calls the second view. The first form works fine, and the second form is also displayed fine, but submitting the second form does not work at all ( I was never able to get to form.is_valid path). Maybe this entire approach of calling one view from another is not correct? What would be the right one?
Please indent your code correctly. Also you are missing an else in the collector function when the request.method is not POST.
I currently have a model form that submits an entered domain to the db.
The problem I'm encountering is, I need to save the currently logged in user's ID (PK from the django.auth table) when a domain is submitted to satisfy a PK-FK relationship on the db end.
I currently have:
class SubmitDomain(ModelForm):
domainNm = forms.CharField(initial=u'Enter your domain', label='')
FKtoClient = User.<something>
class Meta:
model = Tld #Create form based off Model for Tld
fields = ['domainNm']
def clean_domainNm(self):
cleanedDomainName = self.cleaned_data.get('domainNm')
if Tld.objects.filter(domainNm=cleanedDomainName).exists():
errorMsg = u"Sorry that domain is not available."
raise ValidationError(errorMsg)
else:
return cleanedDomainName
and views.py
def AccountHome(request):
if request.user.is_anonymous():
return HttpResponseRedirect('/Login/')
form = SubmitDomain(request.POST or None) # A form bound to the POST data
if request.method == 'POST': # If the form has been submitted...
if form.is_valid(): # If form input passes initial validation...
domainNmCleaned = form.cleaned_data['domainNm'] ## clean data in dictionary
clientFKId = request.user.id
form.save() #save cleaned data to the db from dictionary`
try:
return HttpResponseRedirect('/Processscan/?domainNm=' + domainNmCleaned)
except:
raise ValidationError(('Invalid request'), code='300') ## [ TODO ]: add a custom error page here.
else:
form = SubmitDomain()
tld_set = request.user.tld_set.all()
return render(request, 'VA/account/accounthome.html', {
'tld_set':tld_set, 'form' : form
})
The problem is it gives me an error of: (1048, "Column 'FKtoClient_id' cannot be null"), very odd thing happening, for the column FKtoClient, its trying to submit: 7L instead of 7(the PK of this user's record). Any ideas?
If someone can please help, I would really appreciate it
Firstly, remove FKtoClient from your form. You need to set the user in your view where you can yes the request object. It's not possible to set an attribute on the form that automatically sets the current user.
When instantiating your form, you can pass a tld instance which already has the user set.
def AccountHome(request):
# I recommend using the login required decorator instead but this is ok
if request.user.is_anonymous():
return HttpResponseRedirect('/Login/')
# create a tld instance for the form, with the user set
tld = Tld(FKtoClient=request.user)
form = SubmitDomain(data=request.POST or None, instance=tld) # A form bound to the POST data, using the tld instance
if request.method == 'POST': # If the form has been submitted...
if form.is_valid(): # If form input passes initial validation...
domainNm = form.cleaned_data['domainNm']
form.save() #save cleaned data to the db from dictionary
# don't use a try..except block here, it shouldn't raise an exception
return HttpResponseRedirect('/Processscan/?domainNm=%s' % domainNm)
# No need to create another form here, because you are using the request.POST or None trick
# else:
# form = SubmitDomain()
tld_set = request.user.tld_set.all()
return render(request, 'VA/account/accounthome.html', {
'tld_set':tld_set, 'form' : form
})
This has an advantage over #dm03514's answer, which is that you can access the user within form methods as self.instance.user if required.
If you want to Require that a user be logged in to submit a form, you could do something like:
#login_required # if a user iS REQUIRED to be logged in to save a form
def your_view(request):
form = SubmitDomain(request.POST)
if form.is_valid():
new_submit = form.save(commit=False)
new_submit.your_user_field = request.user
new_submit.save()
You can get the logged in user from the request object:
current_user = request.user
def addbook(request):
if request.method == 'POST':
book_name =request.POST['book_name']
Book = Book.objects.get()
Book.save()
return render_to_response('book_detail.html', {'books': books},context_instance=RequestContext(request))
else:
return render_to_response('addbook.html',context_instance=RequestContext(request))
def book_detail(request):
return render(request, 'book_detail.html')
the above is my view.py i am getting this error"MultiValueDictKeyError at /addbook/"
please help me
That error means that 'book_name' isn't in your POST data.
If you want to handle that case, you can use book_name = request.POST.get('book_name'), which will default book_name to None if it isn't in the POST data.
If not, you need to make sure the form has an input called 'book_name'.