I'm trying to achieve following tasks in Django:
First page: User fills a large Job application form and that data is
sent to Second page
Second page: User reviews his previously filled data and proceeds to third page
Third page: User pays the amount(came from Second page) and once paid, then only all this data is saved to DB.
I've done First page work of filling form and then sending that data to Second page.
Here's my views.py
def applyJob(request,id=None):
job = get_object_or_404(AddJob, id=id)
if request.method == 'POST':
context = {
'jobName': job.jobName,
'jobID' : job.pk,
'cfName' : request.POST.get('candidateFirstName'),
'cmName' : request.POST.get('candidateMiddleName'),
'clName' : request.POST.get('candidateLastName'),
......
return render(request,'reviewAppliedJob.html',context)
else:
context ={
"jobName": job.jobName,
"id": id,
}
return render(request,'applyJob.html',context)
Since I'm sending the context data using return render(request,'reviewAppliedJob.html',context), URL is not changing and so it's not going to my reviewAppliedJob views and so I cannot write code to go to Third page.
def reviewAppliedJob(request):
return HttpResponse('done....')
For that, I can use HttpResponseRedirect('/reviewAppliedJob') instead of render in applyJob() but it will not send my context data. Django allows sending context either using render(), messages framework, url params or session. But since I have large amount of data, I don't know which one to use and will work perfectly.
What's the best way to achieve this task efficiently and securely?
Thanks in advance.
I suggest you use sessions instead. Instead of writing three individual views you can write one. After user fills the data, save them in a session key with a phase key temporarily. In this way, when the view is processed you can access to data and phase of the user.
Related
I am struggling with the update of database information with the forms, and simply passing information between views. I could really use some advice because I am fairly new to Django.
The flow goes like this:
1. First form; I transfer the article price and title to the view "event"
2. The view "event" handles title and price and ask for confirmation in the html form
3. Once confirmed, it directs that information to the view "transact_test", I want this view to handle the update of the database via a new form that is build with the Article model. But it provides the error message : "didn't return an HttpResponse object. It returned None instead."
To fix your error: In transact_test you are just calling render in the request.method == 'POST' block:
render(request, ...)
You need to return render:
return render(request, ...)
You should really take a look at some additional django tutorials you are making this harder than you need to. You should almost never manually render a form when using django. And as Tariq said, please don't use images.
I'm trying to understand how django populates the data in a form when I go back in a browser
In the debugger when I go back in the browser it generates a GET request, not a POST and so the form is not bound and has no self.data.
How do I get the existing values of the fields in a django form when going back in the browser?
(note I am using session with database backend)
While creating the form use initial data.
data = { 'field_1': 'value'}
my_form = MyForm(initial=data)
The error is in the question. The data is coming from the browser cache not the backend.
I am using Boostrap modal fade window which renders Django form to update my database records. And what I fail to do is not to reload the page if the user has opened the Update window and did not change anything. It will be easier to get my idea if you look at the code below:
def updateTask(request, task_id):
#cur_usr_sale_point = PersonUnique.objects.filter(employees__employeeuser__auth_user = request.user.id).values_list('agreementemployees__agreement_unique__sale_point_id',flat=True)
selected_task = Tasks.objects.get(id=task_id)
task_form = TaskForm(instance=selected_task )
taskTable = Tasks.objects.all()
if request.method == 'POST':
task_form = TaskForm(request.POST,instance=selected_task)
if task_form.has_changed():
if task_form.is_valid():
# inside your model instance add each field with the wanted value for it
task_form.save();
return HttpResponseRedirect('/task_list/')
else: # The user did not change any data but I still tell Django to
#reload my page, thus wasting my time.
return HttpResponseRedirect('/task_list/')
return render_to_response('task_management/task_list.html',{'createTask_form':task_form, 'task_id': task_id, 'taskTable': taskTable},context_instance=RequestContext(request))
The question is, is there any way to tell Django to change the url (like it happens after redirecting) but not to load the same page with same data for the second time?
It's not trivial, but the basic steps you need are:
Write some javascript to usurp the form submit button click
Call your ajax function which sends data to "checking" view
Write a "checking" view that will check if form data has changed
If data have changed, submit the form
If not, just stay on page
This blog post is a nice walkthrough of the entire process (though targeted towards a different end result, you'll need to modify the view).
And here are some SO answers that will help with the steps above:
Basically:
$('#your-form-id').on('submit', function(event){
event.preventDefault();
your_ajax_function();
});
Call ajax function on form submit
Gotta do yourself!
Submit form after checking
So I have a a HTML page with a table in it which contains details of a certain model. Each row contains details of a different object. I have a cell for a button as well.
Now, what I want is for the user to be able to click on the button and it should take them to the appropriate page for that particular user that they've clicked on. The way I can do this now is by creating a URL that takes a user_id argument along with a view to redirect it to a template. This url can then be added to the button. However, I don't want the user_id to be shown in the URL (being shown in Inspect Element is okay (as in the row ID)).
This rushed, so sorry. How can I do this?
Is there a way to do it without putting any information whatsoever in the URL?
Thank you!
One way to do this is to send user ids from a POST instead of a GET for getting the user info, when the user clicks the button, you submit a hidden form which contains user_id (which you will update accordingly) and pass it to Django. On this POST call you will wire a render of the page for the user according to the POST parameter you are expecting containing the user id.
You can read the post parameters on a request via:
request.POST.get('user_id')
The downside of this approach is that you won't be able to share the link for a certain user, because the link will only contain the get parameters.
Maybe you can refactor your application to use some kind of SPA framework on the front-end. In this way you can load any content on your current page and the URL never changes if you don't want. Take a look for example at AngularJS or Durandal. Both works well with Django.
You can also solve the problem by using POST instead of GET but in my opinion that's not a very elegant solution because POST requests should be used just when you send data to the server.
If your worried about security I don't think keeping the user_id secret will be effective but if for some other reason you have to do this put it in session and redirect to user page without any parameters.
Put your table inside a form and store the id in an attribute of the button on each row:
<button class="mybutton" data-id="{{ my_object.id }}">view</button>
Put a hidden field at the bottom of your form:
<input type="hidden" id="user_id" name="user_id" />
Javascript:
$("table .mybutton").click(function(e) {
e.preventDefault();
$("#user_id").val($(this).attr("data-id"));
$("#my_form").submit();
});
In your table view:
if request.method == "POST":
request.session["user_id"] = request.POST.get('user_id')
return redirect("user_page")
In your details view:
user_id = request.session["user_id"]
creating urls
If the url is relevant to the user; then use the user_id; e.g. http://example.com/mysite/users/<user_id>/userstuff.
obfuscation is not security.
obfuscation is not a permission scheme.
Other possibilities:
http://example.com/mysite/users/<uniqueusername>/userstuff.
http://example.com/mysite/users/<slug>/userstuff.
http://example.com/mysite/users/<encoded>/userstuff, where encoded is either 2-way encoding, or a field on the user model that is unique.
getting logged in user (request.user)
If the url has nothing to do with the user, but you need to get the authenticated user then read the docs: https://docs.djangoproject.com/en/1.7/topics/auth/default/#authentication-in-web-requests.
def my_view(request):
if request.user.is_authenticated():
# use request.user
else:
# something else
I have an application where a device sends data to my application and the application stores the data.
My Question is What is the best way to send data from the device to the server ?
The Device can be a Smart Phone.
right now I am sending a URL request along with some data like this:
www.example.com:8888/Data/?id=12345&name=john&DOB=25-09-1974
I fetch data with GET Request in Django and then save the data. Is this Right to do ? or should I follow some other process ?
P.S The data is not Sensitive. I mean Security is not a concern.
You shouldn't upload Data to the server via "GET". That is what the "POST" method is for.
According to the HTTP/1.1 Spec:
The POST method is used to request that the origin server accept the
entity enclosed in the request as a new subordinate of the resource
identified by the Request-URI in the Request-Line
In other words, POST is used to create.
It doesn't matter if you think your data is sensitive or not. By implementing a way to alter data on the server, you are automatically offering a way that can be misused by anyone. Hence, all such interfaces have to be treated with the same thoroughness in terms of security.
Your question doesn't provide anything about what you want to to with the transferred data. Do you want to store it persistently in a database or is the data only relevant for the user during his current visit?
Basically you are offered three ways:
1. persistent storage.
You will store the data in your database.
In this case you should use a form with the aforementioned "post" method.
#your_template.html
<form method="post" action="<your action">
<!-- do something -->
{{ form }}
</form>
#your_view.py
def your_view(request):
if request.method == 'POST':
form = YourForm(request.POST)
if form.is_valid(): # All validation rules pass
# Process the data in form.cleaned_data
# ...
return HttpResponseRedirect('/thanks/') # Redirect after POST
else:
form = YourForm() # An unbound form
return render(request, 'your_template.html', {
'form': form,
})
See https://docs.djangoproject.com/en/dev/topics/forms/ for more information about django forms
2. temporary storage.
you are not required to store any of these results persistently, so you can use the session mechanism of django, which will allow you to pass around data which will be just valid while a specific user is visiting your page. You can adjust the time to live of session objects
See https://docs.djangoproject.com/en/dev/topics/http/sessions/ for more information about django sessions
3. client based storage.
Go all the way to the client and use cookies which will be stored on the clients machine and are just read by the server. But you have to be extra thorough while evaluating cookie values.
See Django Cookies, how can I set them? for a little cookie helper for django and take it from there