PLease i need your help, i'm trying to use jeditable to edit a field on a table inside {% for in %}.
editable DIV:
<td><div class="edit" id="{{ c.id }}">{{ c.name|safe }}</div></td>
jeditable code:
<script>
$(document).ready(function(){
$('.edit').editable('/categoryedit/{{ c.id }}/', {
style: 'display: inline'
});
});
</script>
Url:
url(r'^categoryedit/(?P<id>\d+)/$', 'pos.views.CategoryEdit'),
View:
def CategoryEdit(request, category_id):
id = request.POST.get('category_id', '')
value = request.POST.get('value', '')
categoria = Category.objects.get(pk=id)
categoria.name = value
categoria.save()
return HttpResponse(escape(value))
Solution : The problem was that the editable DIV was inside a {% for %} bucle and in that case is needed to use .each en the Javascript like this...
$('.edit').each(function(){
$('.edit').editable('/categoryedit', {
});
});
and is not necessary to pass the parameters in the url ("/category/1") instead is better to get the parameters using ...
c_id = request.POST.get('id')
the View must be like this:
def CategoryEdit(request):
if request.is_ajax():
if request.method == 'POST':
txt = request.POST.get('value')
c_id = request.POST.get('id')
categoria = Category.objects.get(pk=c_id)
categoria.name = txt
categoria.save()
return HttpResponse(txt)
You probably need to add CSRF data to your javascript. I just ran into this and posted it here:
Django and JEditable: CSRF error
One way to see for sure is to use firebug and look at the ajax response coming back from Django. (If the CSRF info is missing, the Jeditable AJAX call throws a 403 Forbidden error.)
Related
In my Django web app, I'm trying to dynamically update only a certain section of my page via AJAX, but doing so by returning/replacing HTML in a child template ({% include 'keywords.html' %}). I understand that I can (and maybe should) return a JsonResponse (and I have done so successfully), but I'd like to try and get the below implementation working (as others seem to have).
The view successfully returns the HTML to the AJAX response, but lacking the data contained in the keywords context variable.
templates/index.html
...
<div id="keywords">
{% include 'keywords.html' %}
</div>
...
templates/keywords.html
<div id="keywords">
{% if keywords %}
{% for keyword in keywords %}
<p>{{keyword.word}}</p>
{% endfor %}
{% endif %}
</div>
views.py
def add_keyword(request):
if request.method == 'POST':
form = KeywordForm(request.POST)
if form.is_valid():
...
keywords = Keywords.objects.values()...
print(keywords) # this works, contains a queryset with data
context = {
keywords: keywords,
}
# i've also tried return HttpResponse(render_to_string(...))
# with same result
return render(request, 'keywords.html', context))
index.js
// i've also tried jquery .load()
$.ajax({
url: data.url,
type: "POST",
data:
{
keyword: keyword,
csrfmiddlewaretoken: data.csrf_token
},
success: function(data) {
$("#keywords").html(data);
}
});
AJAX Response data:
<div id="keywords">
</div>
What might I be missing, or doing wrong?
In your context you are missing quotes, when returning the page you have one extra parentheses. It works on my system.
You can render your template with context data using the loade and context
it will do first templates using jinja context will render in html then return final html text then you can pass using JsonResponse
try following stuff then let me know
#view.py
from django.template import context,loader
...
def render_view(request):
if request.method == 'GET':
form = KeywordForm(request.POST)
if form.is_valid():
keywords = Keywords.objects.values()
print(keywords) # this works, contains a queryse
context = {
keywords: keywords,
}
template = loader.get_template('keywords.html')
html = template.render(context)
print(html)
return JsonResponse({'html':html},status=200,content_type="application/json")
#in ajax call success method you should render
success: function(data) {
$("#keywords").html(data);
//or
//ordocument.getElementById('keywords').innerHTML=data;
}
if works or not let me know?
I created my first site with Django and I'm trying to make the Ajax "like" button work on the listing posts page, but I have to reload the page to have +1.
My views:
def likes_post(request):
post_id = None
if request.method == 'GET':
post_id = request.GET['post_id']
like = 0
if post_id:
post = Post.objects.get(id = int(post_id))
if post:
like = post.likes + 1
post.likes = like
post.save()
return HttpResponse(like)
My HTML template:
{% for post in posts %}
<div class="post-favourite">
J'aime <i class="fa fa-heart-o likes_count"aria-hidden="true"> {{ post.likes }}</i>
</div>
{% endfor %}
and the Ajax function:
<script type="text/javascript">
$('.like').click(function(){
var ps_id;
ps_id = $(this).attr("data-posts-id");
$.get('/likes_post/', {post_id: ps_id}, function(data){
$(this).prev().find('.like_count').html(data);
});
});
</script>
The Ajax button for the post detail page works by simply replacing the last line with
$('.like_count').html(data);
in your views.py, you should send back data to jquery with JsonResponse
from django.http import JsonResponse
def likes_post(request):
post_id = None
if request.method == 'GET':
post_id = request.GET['post_id']
like = 0
if post_id:
post = Post.objects.get(id = int(post_id))
if post:
like = post.likes + 1
post.likes = like
post.save()
return JsonResponse({'like':like})
and then in your jquery:
<script type="text/javascript">
$('.like').click(function(){
var ps_id;
ps_id = $(this).attr("data-posts-id");
$.ajax({
url: '/likes_post/',
method: 'GET',
data: {
'post_id': ps_id,
},
success: function(data){
$(this).prev().find('.like_count').html(data);
$(this).html(data);
}
});
});
</script>
whatever you send with JsonResponse is accessible in success part of jquery. in this example the like we send is data in success part.
in success part you can write data in your html code
First, I'm relatively new to Django. I've seen my question addressed here with answers that I've tried to implement without success. Using a date picker that formats the date differently then how its stored and returned on the form initially.
forms.py
....
start_date = forms.Datefield(widget=forms.DateInput(format='%m/%d/%Y'), input_formats=['%m/%d/%Y'])
queries.html
....
<div class="col-4">
<label for="start_date" style="font-weight: bold;">Start Date</label>
<div class="input-group date" data-provide="datepicker">
<input type="text" name="start_date" id="start_date" value="{{queryform.start_date.value}}" class="form-control">
<div class="input-group-addon"><span class="glyphicon glyphicon-th"></span></div>
</div>
</div>
....
<form method="post">
{% csrf_token %}
<script>
$(function() {
$( ".datepicker" ).datepicker({
changeMonth: true,
dateFormat: 'mm/dd/yyyy',
changeYear: true,
yearRange: "2010:2025"
});
});
</script>
url.py
path('editqueries/<id>', views.editqueries, name='editqueries'),
views.py
def editqueries(request, id):
query_data = get_object_or_404(Query, pk=id)
if request.method == "POST":
query_form = QueryForm(request.POST, instance=query_data)
if query_form.is_valid():
the_query_name = query_form.cleaned_data["query_name"]
# get the hidden field from the html page (but not on the
# Django form)
current_query_name = request.POST["currentqueryname"]
# test to be sure if the names are not the same that changing
# the name doesn't create a duplicate query_name
if not the_query_name == current_query_name:
try:
test_query =
Query.objects.get(query_name=the_query_name)
except Query.DoesNotExist:
# this is allowed. Named changed does not create a
# duplicate
query_form.save()
query = Query.objects.all()
query_flag = "None"
context = {'queries': query, 'query_flag': query_flag}
return render(request, 'seakerUI/queries.html',
context)
# successful query means this name is in use.
# Stop the renaming of the query.
return HttpResponse("ERROR: Query Name '" +
the_query_name + "' Already exist!")
query_form.save()
query = Query.objects.all()
query_flag = "None"
context = {'queries': query, 'query_flag': query_flag}
return render(request, 'seakerUI/queries.html', context)
else:
return HttpResponse("Form is invalid.. errors:" +
str(query_form.errors))
else:
query_form = QueryForm(instance=query_data)
# tell the user the query is ready to be updated.
query_flag = "Edit"
context = {'queryform': query_form, 'query_flag': query_flag}
return render(request, 'seakerUI/queries.html', context)
queries.html
see code above
So when attempting to edit a query, the page is formatted with the date like "Aug. 2, 2019". However, if one submits the form without changing the date, the form is invalid and the form.error is date is invalid.
I've set the following line in settings.py
DATE_INPUT_FORMATS = ['%m/%d/$Y']
I've had 2 other formats in this definition but none seem to work.
I also executed
python manage.py diffsettings
and though it shows in the output the impact is negligible.
I've attempted using many examples of structuring the forms.py file using a widget function and without it without success. The problem does not appear to be with the javascript on the hmtl page.
NOTE: If I change the date when the edit query page presents it then the form validates. However, if one doesn't change the date and the form is submitted it is not valid and an error occurs. I shouldn't have to change the date to get the form to validate.
Suggestions?
You can try with html5 and WTF forms.
Html5 and WTFforms together can be used to select and date/month/year and process.
In form.py:
from wtforms.fields.html5 import DateField
Accept the inputs as shown :
dob= DateField('Password - Your Date of Birth', validators=[DataRequired()], format='%Y-%m-%d')
In html
form.dob(class="form-control form-control-lg")
I am using django 1.5, python 2.7 and jquery 1.9. I have a form which has precisely 2 fields i.e. title and document. When I press submit I want the users chosen document to be present in the request.FILES as shown in the view.
When I submit the regular form (without ajax), this works fine, but with ajax I do not get the file field in my request. Any suggestions on how to upload a file using ajax.
HTML:
<form enctype="multipart/form-data" action="{% url 'upload_document' %}" method="post" id="uploadForm">
{% csrf_token %}
<ul>
<li>
<div>Title</div>
<input id="title" type="text" maxlength="200"/>
<div class="error"></div>
</li>
<li>
<div>Upload File</div>
<input id="document" type="file" size="15" />
<div class="error"></div>
</li>
</ul>
<input type="submit" value="submit"/></p>
</form>
FORMS.PY:
class UploadForm( forms.Form ):
document = forms.FileField()
title = forms.CharField(max_length = 200)
def clean(self):
cleaned_data = super(UploadForm, self).clean()
return cleaned_data
def save(self, *args, **kwargs):
title = self.cleaned_data['title']
doc = self.cleaned_data['document']
document = Document(title = title, document = doc)
document.save()
return document
SCRIPT:
<script type="text/javascript">
$("#uploadForm").submit(function(event){
event.preventDefault();
$.ajax({
url : "{% url 'upload_document' %}",
type: "POST",
data : {csrfmiddlewaretoken: document.getElementsByName('csrfmiddlewaretoken')[0].value,
title: document.getElementById('title').value,
//document: document: document.getElementById('document'),
},
dataType : "json",
success: function( response ){
if(response == "True"){
// success
}
else {
//append errors
}
}
});
});
</script>
VIEWs.PY
def upload_document(request):
print request.POST
print request.FILES
if request.is_ajax():
if request.method == 'POST':
form = UploadForm(request.POST, request.FILES, user = request.user)
if form.is_valid():
form.save()
return HttpResponse(simplejson.dumps('True'), mimetype = 'application/json' )
else:
errors = form.errors
return HttpResponse(simplejson.dumps(errors), mimetype = 'application/json' )
The answer to that question is not that simple. First of all if you intend to support old browsers then indeed it gets nasty. You have to deal with hidden iframes and some JavaScript tricks. I do advice using some well-known scripts for that like jQuery-File-Upload.
But the world is evolving and new technologies arise including HTML5. There's a new File API which is available in most modern browsers ( IE10+, FireFox3.6+, Chrome13+, see: http://caniuse.com/fileapi ) which can be used for that. First you need some HTML:
<input type="file" id="file-select" />
Then you can bind to (for example) change event:
$('#file-select').change( handleFileSelect );
and finally the handler itself:
var data = {};
function createReaderHandler(name) {
return function(ev) {
data[name] = ev.target.result;
};
}
function handleFileSelect(ev) {
var files = ev.target.files; // FileList object
// Loop through the FileList
for (var i = 0; i < files.length; i++) {
var file = files[i],
name = file.name || file.fileName,
reader = new FileReader();
reader.onload = createReaderHandler(name);
reader.readAsText(file);
}
}
Once the data is loaded into JavaScript memory (note that the operation is asynchronous) you can send it via AJAX like any other data. There are more options: depending on your file you can read it as a binary data using .readAsBinaryString and so on. Google is your friend. :)
Also I think there already are good scripts for uploading files with a fallback to old methods. This one can be interesting (haven't tried it):
http://www.plupload.com/
I think the issue is in the submit button, change it into normal button
ie, <button type='button' id='submit'>submit</button>(by default all buttons in form are submit)
and the ajax as
$('#submit').on('click',function(){
frm = $(this).parents('form')
$.ajax({
type: frm.attr('method'),
dataType:'json',
url: frm.attr('action'),
data: frm.serialize(),
async: false,
success: function (data) {
console.log('success')
},
error: function(data) {
console.log("Something went wrong!");
}
})
All others will be same
Just try it will work
I am doing ajax using jquery in django1.3,well its works fine. Am using jquery load method to fill a in a template.
I get a json object asychrosily when user cliks in a button.I pass it to another template(which i loading inside the div of first template ) as a dictionary. But am unaware of how I display it in template.(I tried to pasres json in template page),but its leads to error.
Can any one suggest How can solve the problem?
So I used normal way parse json in view and pass it to template by using the method locals() in render_to_response(). Is it a good approch?
testjqyery.html
$(document).ready(function() {
$('#save').click(function(e)
{
e.preventDefault();
$( '#results' ).html( ' ' ).load( '{% url t %}' );
});
<div id="results"></div>
views.py
def testupdater(request):
// getting json from server
//contents_json = json.loads(...)
json_data = {'json_dict': contents_json}
return render_to_response( 'results.html' ,json_data,context_instance=RequestContext(request))
results.html
{% if json_dict|length %}
{% else %}
{% endif %}
try it this way
from django.utils import simplejson
data = []
data.append({"msg": 'Hi this message'})
json = simplejson.dumps(data)
return HttpResponse(json, mimetype='application/json')