in views:
return render_to_response("main.html", RequestContext(request, {'form':form, "result":result}))
in template i have this jquery function:
$('#submitButton').click(function(e) {
e.preventDefault();
var dataPosted = $("#mainSubmit").serialize();
$.ajax({
type: "POST",
data: dataPosted,
url: 'main/',
success: function(data) {
$("#mainDiv").html(data);
$(".response").html({{ result }});
$(".response").show();
}
});
});
});
<div id="mainDiv" class="part">
<form id="mainSubmit" action="main/" method="POST" name="submitForm">
{% csrf_token %}
{{ form.non_field_errors }}
{{ form.as_p }}
<input type="submit" value="Submit" id="submitButton"/>
<div class="response" style="display: none;"></div>
</form>
</div>
but it seems that data can't be assigned to response div like this(it seems data is not defined). So i don't know what is the way to send data to template. if i use Httpresponse(result) in views, then i can't have my form refreshed, and only i can display in response div data i send from view. so what is the way?
EDIT:
This is my views. before, i didn't put else for the condition if form.is_valid(): , but here i use, because i think if i don't do this, it might cause some probables. i don't know what is the best way.
def mainFunc(request):
if request.is_ajax():
if request.method == 'POST':
form = mainForm(request.POST)
if form.is_valid():
// process the form
result = "successful"
to_json = {'form':form, 'result':result}
return HttpResponse(json.dumps(to_json), mimetype='application/json')
else:
result = ""
to_json = {'form':form, 'result':result}
return HttpResponse(json.dumps(to_json), mimetype='application/json')
else:
form = mainForm()
return render_to_response('main.html', RequestContext(request, {'form':form}))
else:
return render_to_response("ajax.html", {}, context_instance=RequestContext(request))
You need to return a response in format like JSON
You can use this snippet or more simple code like this:
from django.utils import simplejson
to_json = {'form':form, "result":result}
return HttpResponse(simplejson.dumps(to_json), mimetype='application/json')
Then you will be able to use data.result and data.form in your JS code.
If you use the same view for ajax and non-ajax call you can check for it with request.is_ajax()
Also you will not be able to use template tags and filters in your JS callback. So you need to pre-render your form before sending it via JSON
So the final code:
to_json = {'form':form, "result":result}
if request.is_ajax():
to_json['form'] = to_json['form'].as_p()
return HttpResponse(simplejson.dumps(to_json), mimetype='application/json')
else:
render_to_response("main.html", RequestContext(request, {'form':form, "result":result}))
Edit I assume that ajax.html is the template for the whole page and main.html is the template for mainDiv part of the page
So in is_ajax() part of you view you can return the data like this.
to_json = {}
to_json['form'] = render_to_string('main.html', {'form': form}, context_instance=RequestContext(request))
to_json['result'] = result
return HttpResponse(json.dumps(to_json), mimetype='application/json')
And you always return data like this, both for GET and POST AJAX calls
And in JS you get data like this:
$("#mainDiv").html(data.form);
$(".response").html(data.result);
$(".response").show();
Related
I am trying to use Toastr to pass status messages upon completion of a form. If the form is valid it returns you to the index using "return index(request)" I want to pass context through this.
I am running Python 3.6 and Django 1.11, using Modelforms. I have tried passing context=var_list as well as passing the variables individually.
Line 15-34 of my views.py
def add(request):
form = CustomerForm()
if request.method == "POST":
form = CustomerForm(request.POST)
if form.is_valid():
form.save(commit=True)
notification_vars = {"toastr_title": "SUCCESS!",
"toastr_message": "The Customer has been added to the database",
"toastr_type": "success",}
return index(request, context=notification_vars) // THIS IS WHAT I NEED TO WORK
page_vars = { "page_title": "Add Customer",
"page_icon": "fa-address-book",
"toastr_title": "",
"toastr_message": "",
"toastr_type": "",
"form": form}
return render(request, 'customers/add.html', context=page_vars)
This is the toaster code in my footer, and why I always have to pass the variables as blank unless I want to pass a message
{% if toastr_message %}
<script>
var title = '{{ toastr_title }}',
message = '{{ toastr_message }}',
type = '{{ toastr_type }}',
options = {};
toastr[type](message, title, options);
</script>
{% endif %}
What I want to do is on successful form submission, it passes the context back tot he index page and fills the script in the footer so the success message pops up.
Currently, it comes back telling me I have an unexpected variable Context, or if I pass the variables directly, it tells me there is a syntax issue
I figured it out. I needed to make sure my Index could take context, but also make it so that if no context is passed it still works.
def index(request,context={"toastr_title":"","toastr_message":"", "toastr_type":"" }):
customer_list = Customers.objects.order_by('Name')
page_vars = { "page_title": "Customers",
"page_icon": "fa-address-book",
"toastr_title": context['toastr_title'],
"toastr_message": context['toastr_message'],
"toastr_type": context['toastr_type'],
"customer_records": customer_list}
return render(request, 'customers/index.html', context=page_vars)
I am trying to display a comment form on a page. So far I have created a link and I want that each time that link is clicked it displays the form on the same page as where the link is but my problem here is that the link redirects me to another page, which I don't want.
urls.py
url(r'^all/$', 'posts.views.articles'),
url(r'^get/(?P<post_id>\d+)/$', 'posts.views.article'),
url(r'^articles/$', 'posts.views.create'),
url(r'^like/(?P<post_id>\d+)/$', 'posts.views.like_article'),
url(r'^article/(?P<post_id>\d+)/$', 'posts.views.add_comment'),
views.py
def articles(request):
args = {}
args.update(csrf(request))
args ['posts'] = post.objects.filter(user = request.user)
args ['full_name'] = User.objects.get(username = request.user.username)
args ['form'] = PostForm()
return render_to_response('articles.html', args)
def article(request, post_id=1):
return render(request, 'article.html',
{'post': post.objects.get(id=post_id) })
def add_comment(request, post_id):
a = post.objects.get(id=post_id)
if request.method == "POST":
f = CommentForm(request.POST)
if f.is_valid():
c = f.save(commit=False)
c.pub_date = timezone.now()
c.article = a
c.save()
messages.success(request, "You Comment was added")
return HttpResponseRedirect('/posts/get/%s' % post_id)
else:
f = CommentForm()
args = {}
args.update(csrf(request))
args['post'] = a
args['form'] = f
return render_to_response('article.html', args)
#return HttpResponseRedirect('/posts/all')
article.html
<h2>Comments</h2>
{% for c in post.comment_set.all %}
<p>{{c.name}} : {{c.body}}</p>
{% endfor %}
<form action="/posts/article/{{post.id}}/" method="post">{% csrf_token %}
<ul>
{{form.as_ul}}
</ul>
<input type="submit" name="submit" value="Post Comment">
</form>
{% endblock %}
As from your question you want submit a comment in your article and when you submit the comment you want to redirect it to the same article page... If you are willing to do this then here is example:
First create a comment submit form either using model form or just form:
class CommentCreationForm(forms.ModelForm):
class Meta:
model = Comment
fields = ('comment_body',) # Set your field for comment
Now pass this form as context in ur article view. Like you did above.
def articles(request):
args = {}
args.update(csrf(request))
args ['posts'] = post.objects.filter(user = request.user)
args ['full_name'] = User.objects.get(username = request.user.username)
args ['comment_form'] = CommentCreationForm
return render_to_response('articles.html', args)
Your article.html
<h2>Comments</h2>
{% for c in post.comment_set.all %}
<p>{{c.name}} : {{c.body}}</p>
{% endfor %}
<form action=""{% url "comment_submit" post.id %}"" method="get">{% csrf_token %}
<ul>
{{form.as_ul}}
</ul>
<input type="submit" name="submit" value="Post Comment">
</form>
{% endblock %}
Catch the url with url(r'^comment/(?P<pk>\d+)/',CommentSubmitView, name="comment_submit"), and write a view.
def AnswerSubmitView(request, pk):
post = Post.objects.get(id=pk) # Get what you have set for your article
comment_text = request.GET.get('comment_body',False)
com = Comment()
post = post # or anything that you have named for your article..
com.comment_body = comment_text
com.save()
return HttpResponseRedirect('/post/%s' % pk) # Your url for your article I guess...
Enjoy...
Use an ajax call to fetch the form from the server without refreshing the page. This requires jQuery. Replace the placeholder selectors I've used with whatever you need for your app. I'd recommend wrapping all of article.html in a div and give that an id tag (and refer to this tag where I use '#form-id' selector below), so you know when the form is already displayed and you can access the entire chunk.
Also note that I'm not entirely sure how to get the html from render_to_response. Just figure out what kind of object is sent back to the ajax caller and how to get the html from that object. Shouldn't be hard.
Adapt and add the following to the bottom of the template containing the link to add the form
<script>
var showForm = function(url) {
$.ajax({
type: 'GET',
dataType: 'json',
url: url,
success: function(data, status, xhr) {
// Not positive if this is how things work with render_to_response
// I usually use render_to_string for this and just return pure HTML
$('#div-to-display-form-in').append(data);
},
error: function(error) {
// Handle error
}
});
}
$(document).ready(function() {
$('#link-to-show-form').click(function(event) {
event.preventDefault();
// The conditionals check if form is already showing
// If form already showing and link clicked again, form is removed
if ($('#form-id').length === 0) {
showForm($(this).attr('href'));
} else {
$('#form-id').remove();
}
});
});
</script>
I've made a django form to edit values in a module and it is working ok in a single page, not problem so far.
The problem arise when I want to use that form in a state. Currently, I'm using Angular ui- router to display states in a navigation bar. When I click on the "save button" the post action is not being received by the django form.
It's like that I have to route the post method to pass the values first into angular and then into the form(backend).
Any help is appreciated.
Check my code:
views.py
def InstitutionDetailView(request):
client = get_object_or_404(ClientProfile, user=request.user)
institution = Institution.objects.get_or_create(client=client.id)[0]
if request.method == 'POST':
form = EditDetailsForm(request.POST, instance = institution)
if form.is_valid():
form.save()
return render_to_response('account/client/details.html',
{'form': form, 'institution':institution}, context_instance=RequestContext(request))
else:
form = EditDetailsForm(instance = institution)
return render_to_response('account/client/details.html',
{'form': form, 'institution':institution}, context_instance=RequestContext(request))
urls.py
url(r'^user/client/details.html', auth(views.InstitutionDetailView), name="institution_edit_details"),
details.html
<form method="post" action="">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Edit">
</form>
app.js
angular.module('account.client', ['ui.router', 'ngTable'])
.config(function ($stateProvider, $interpolateProvider, $urlRouterProvider) {
//allow django templates and singular to co-exist
$interpolateProvider.startSymbol('[[');
$interpolateProvider.endSymbol(']]');
$urlRouterProvider
.when('/institution','/institution/details')
.otherwise('/home');
$stateProvider
.state('home', {
url: '/home',
templateUrl: 'client/dashboard.html'
})
.state('institution', {
url: '/institution',
templateUrl: 'client/institution/'
})
.state('institution.details', {
url: '/details',
templateUrl: 'client/details.html'
});
})
I'm trying to upload multiple files in one request using dropzone.js. When I set the uploadMultiple option to true in dropzone, one request containing both files is sent to my view, but form validation fails.
Here is my Django form:
class UploadForm(forms.Form):
data = forms.IntegerField(widget=forms.HiddenInput())
file = forms.FileField()
My view:
def upload(request):
if request.method == 'POST':
form = UploadForm(request.POST, request.FILES)
print request.FILES
if form.is_valid():
for file in request.FILES.getlist('file'):
print str(file)
else:
print form.errors
else:
form = UploadForm(initial={'data': 5})
return render(request, 'upload.html', {
'form': form
})
and my template:
<script type="text/javascript">
Dropzone.options.myAwesomeDropzone = {
autoProcessQueue : false,
uploadMultiple: true,
init : function() {
myDropzone = this;
this.element.querySelector("input[type='submit']").addEventListener('click', function(event) {
event.preventDefault();
event.stopPropagation();
myDropzone.processQueue();
});
}
}
</script>
<form id='my-awesome-dropzone' class="dropzone"
action="{% url 'upload.views.upload' %}" method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.data }}
<input type="submit" value="Upload" />
</form>
I see that request.FILES has two files:
<MultiValueDict: {u'file[]': [<InMemoryUploadedFile: Forest Flowers.jpg (image/jpeg)>,
<InMemoryUploadedFile: Forest.jpg (image/jpeg)>]}>
I guess the issue is Django doesn't recognize file[]. It expects file instead. How can I get Django to recognize the two uploads?
You are right assuming that the validation error is originated because of the input name dropzone.js sends to the server. The "file[n]" pattern when your Django form is expecting a field named "file" throws a validation error (required field).
In Dropzone.js you can specify the parameter "paramName" and this object property also accepts a function instead of a simple string, so if you set your paramName to something like:
...
paramName: function(){
return "file";
}
...
the name of the field sent to server doesn't change and you get a "file" field in request.FILES that is a dict with one element (file) that is an array of files as it is expected.
You just need to do:
file1 = request.FILES.get(file[][0], None) # For the first file
file2 = request.FILES.get(file[][1], None) # For the second file
... and so on...
Hope that helps.
Initially i am loading a modelform with an instance in the template end. But i have to change the instance upon some action using ajax and then refresh the form in the template end. Please suggest me is there any way to do that?
Normally, the server view uses a ModelForm to render a HTML snippet representing an instance of a Model (i.e. {{ myform.as_p }} or similar) that is then placed in a larger template representing an entire HTML document and finally sent to the client.
You need to create a second view that will render and return only the HTML snippet representing the form. From your original template you can then create an ajax call to your new view, which will return the forms HTML. You can replace your existing form with this via jQuery.
view:
def my_second_form(request):
if request.method == "POST":
form = MyForm(request.POST)
if form.is_valid():
...
else:
form = MyForm()
return render(request, 'my_second_form.html', {
'form': form,
})
template:
<form action="/url/to/my_second_form/" method="post">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit" />
</form>
#djanog function.
def get_doctor_Data(request):
get_doctor = Doctor.objects.get(id=request.GET.get('dept_id'))
# Set initial value of django forms input and send as ajax respons
# If you getting any type of error so use form_name.as_p() method.
edit_form = AddDoctorForm(initial={'name':get_doctor.name, 'dep_id':get_doctor.id})
return HttpResponse(edit_form)
// Ajax method call.
$.ajax({
url: '/department/get_department_Data/',
type: 'GET',
data : {'dept_id': $(this).attr('id')},
success:(data)=>{
if(data){
// open modal
$('#basicModal').modal('show');
// Django forms get using ajax
$('#editForm').html(data)
}
}
})