I am going to add a button in my page to upload file.User clicks this button and choose file from computer, the page will upload file to the server and show a message like 'Upload successfully' to the user.
I have noticed that Django has Filefield in model and we can define a class FileForm so that we can use form = UploadFileForm(request.POST, request.FILES) and form.save() to upload.
However,as I want to refresh part of the page after upload, it comes to me to use ajax to send data.Furthermore,in order to use request.FILES which requires that request has the attribute enctype="multipart/form-data", I think maybe we can use FormData() in ajax.
html:
<div>
<input type="file" name="" id="ul_input">
<input type="hidden" name="local_id" id="get-local-id" value="{{ record.local_id }}"/>
</div>
Javascript:
// grab your file object from a file input
$('#ul_input').change(function () {
var formData = new FormData();
formData.append("ul_file", this.files[0]);
formData.append("filename", this.files[0].name);
formData.append("local_id", $('#get-local-id').val());
$.ajax({
url: 'uploadfile',
type: 'POST',
data: formData,
processData: false,
contentType: false,
dataType: "json",
beforeSend: function () {
console.log("loading...please wait");
},
success: function (responseStr) {
if (responseStr.status === 0) {
alert('upload successfully');
} else {
alert("upload fail");
}
},
error: function (responseStr) {
console.log("error");
}
});
});
views.py
def order_upload(request):
status = 1
if request.is_ajax():
local_id = request.POST.get('local_id')
post = DetailList.objects.get(local_id=local_id)
post.order_dir = request.FILES['ul_file']
post.save()
status = 0
return HttpResponse(json.dumps({'status': status}), content_type='application/json')
models.py
def file_directory_path(instance, filename):
return 'file_list/{0}{1}/{2}'.format(instance.upload_date.strftime('%Y'),
instance.upload_date.strftime('%m'),
filename)
class DetailList(models.Model):
local_id = models.IntegerField(...)
start_date = models.DateField(...)
order_dir = models.FileField(upload_to=file_directory_path, blank=True, null=True)
Dont forget to set MEDIA_ROOT = '/media/' in settings.py
I try to upload a file 'test.docx'.Now it seems that I have alreay uploaded file to media/file_list/201807/test.docx.I also check order_dirin table,it has already become file_list/201807/test.docx.And I got the alert says 'upload successfully'.
However,I can't find my 'test.docx' in directory 'media/file_list/201807/test.docx'.
Where is the file I uploaded? Can anyone help?
Related
I'm using ajax, python, Django, HTML, and javascript for my project.
I'd like to know, if there is a p in my HTML file like,
<p class='text_box', id='tbox'>
{{ text_variable_from_python }}
</p>
<input class='input_box', id='ibox', type='text'>
And if I'd input some text into the input box, make a simple ajax request with the "text" variable and get an output from the server, which I would update on the views.py as,
def main(request):
if request.method == 'POST':
new_text = request.POST['text']
context = {'text_variable_from_python': new_text}
else:
context = {'text_variable_from_python': 'You can change me!'}
print(context)
return render(request, 'Main.html', context=context)
My question is, how do I send the data dynamically from the server to appear on client's webpage using ajax and python in between the two?
Using my method, I can only see "You can change me!" on the webpage or nothing at all. No matter how many differing prompts I give, further changes do not show on the webpage.
EDIT:
My ajax code for sending the variable.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script>
function update_dialogue() {
$.ajax({
type: "json",
url: "update_text",
success: function(data) {
document.getElementById("tbox").value = data['text_variable_from_python'];
}
});
}
My ajax code for recieving the variable.
<script>
function getInputValue() {
let inputVal = document.getElementById("ibox").value;
document.getElementById("ibox").value = '';
$.ajax({
type:'POST',
url: 'main',
data: {csrfmiddlewaretoken: "{{ csrf_token }}",
'text': inputVal,}
});
}
</script>
html
<div>
{{ productform.vendorid|as_crispy_field }}<a id="vendor_id_search" class="btn btn-info">search</a></br>
<div style="display:none;" id="show_vendorname">hjkh</div><br>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
$("#vendor_id_search").click(function (event) {
event.preventDefault();
var vendor_id = $("#id_vendorid").val();
$.ajax({
url: '/ajax/find_vendorname/',
method: 'GET',
data: {
'vendor_id': vendor_id
},
dataType: 'json',
success: function (data) {
$("#show_vendorname").show(data)
}
});
});
views.py
#vendor_name_find_ajax
def find_vendorname(request):
if request.is_ajax():
vendorid = request.GET.get('vendor_id', None)
username = CustomUser.objects.filter(first_name=vendorid)
return username
I want to display the related name from the database table for that vendorid after the user typed the vendorid field and once clicked the button, the related name should be displayed on that particular div. Here, I have made a mistake and don't know to get that value.
$("#show_vendorname").show(data) unhide the div, but don't set in the data.
You need set the data before with $.html()
$("#show_vendorname").html(data).show()
EDIT:
Besides, your view needs to return a HttpResponse:
from django.http import HttpResponse
def find_vendorname(request):
if request.is_ajax():
vendorid = request.GET.get('vendor_id', None)
username = CustomUser.objects.filter(first_name=vendorid)
return HttpResponse(username)
I try to upload a file to django from html through an ajax call.
CLIENT SIDE:
<input type="file" class="text-field" name="media">
<input type="button" class="btn" value="SEND">
var files;
$('.text-field').change(function(){
files = this.files;
console.log(files);
});
$('.btn').click(function(){
var data = new FormData();
$.each(files, function(key, value){
data.append(key, value);
console.log(key + ' : ' + value);
console.log(value);
});
$.ajax({
type: 'POST',
url: 'url',
enctype: 'multipart/form-data',
data: data,
cache: false,
dataType: 'json',
processData: false,
contentType: false,
success: function(data){
console.log(data);
}
});
BACK side:
#csrf_exempt def my_file(request):
print request.POST
print request.FILES
result:
MultiValueDict: {u'0': [TemporaryUploadedFile: about.php (application/octet-stream)]}
Please help me to understand how I can upload a file
To upload a file through Django, you will most likely have to use django forms. Here is an example as for how to upload a file:
def upload_file(request):
if request.method == 'POST':
form = UploadFileForm(request.POST, request.FILES)
if form.is_valid():
instance = ModelWithFileField(file_field=request.FILES['file'])
instance.save()
return HttpResponseRedirect('/success/url/')
else:
form = UploadFileForm()
return render(request, 'upload.html', {'form': form})
As you can see the form validates your input, and then you can save the file in to your server. For more information about this topic please use the django documentation:
https://docs.djangoproject.com/en/1.10/topics/http/file-uploads/
I'm newer in Django and some time ago I've totally stuck on problems with my requests. I'm trying to do POST from Django form. I do that with json and AJAX
Here is my code
form.py
class PostForm(forms.ModelForm):
class Meta:
model = Message
fields = ['message_text']
widgets = {
'message_text': forms.TextInput(
attrs={'id': 'message_text', 'required': True,
'placeholder': 'new message...', }),}
views.py
def index(request):
if request.method == 'POST':
form = PostForm(request.POST)
if form.is_valid():
form.cleaned_data
message_t = request.POST.get('message_text')
response_data = {}
new_mess = Message(message_text = message_t,
post_time = message_t.created,
username="second")
new_mess.save()
response_data['result'] = message_t
else:
response_data['result'] = 'nothing...'
else:
form = PostForm()
template = loader.get_template('chat/index.html')
context = RequestContext(request, {
'form': form, })
return HttpResponse(template.render(context))
(In another variant of views.py I tried to separate POST request handling to another function, but it doesn't work as well)
html:
<form method="POST" id="post-form">
<td class="col-lg-6"><div class="fieldWrapper" id="the_post"
class="form-control" type="text">
{{ form.message_text }}
</div></td>
<td class="col-lg-6"> <input type="submit" value="Post"
class="btn btn-success" name = "Post"></td>
</form>
js:
$(function() {
$('#post-form').on('submit', function(event){
event.preventDefault();
console.log("form submitted!") // sanity check
create_post();
});
function create_post() {
console.log("create post is working!") // sanity check
$.ajax({
url : "/chat/new_message/", // the endpoint
type : "POST", // http method
data : { the_post : $('#post-form').val() },
success : function(json) {
$('#post-form').val(''); // remove the value from the input
console.log(json); // log the returned json to the console
console.log("success");
},
error : function(xhr,errmsg,err) {
...
}
});
};
});
In the result my POST is successful, no error appears, but no record in the base created too.
Note: Also I've excluded csrf everywere
Can someone help me to figure out what's wrong?
The form is not valid. It can never be valid, because you are sending a JSON dictionary with the form data inside the key "the_post", but you haven't told the view to look there.
And the view can't report back the status of the form, because you construct a response - "response_data" - and then ignore it.
Finally, your view does not send back JSON anyway - it sends back the rendered template, as if it were a normal non-Ajax view - so the receiving JS has no idea what to do with it.
I've found the fix for my POST.
The main problem was in json body, I was using wrong value name, it has to be:
data : { the_post : $('#message_text').val() },
Now request is not empty.
I am trying to call my view from django template via an Ajax call.
I want the form object in response from view such that I can render this form via jquery in a div element.
Is it possible ? How?
This is what i tried:
home.html
function get_edit_form(button, id)
{
$.ajax({
url: "/manage/licenses/{{mls_signup_code}}/{{agent_id}}/" + id + "/",
type: "get",
data: {id: id},
success: function(response) {
console.log(response);
$("#formdiv").html({{ response.as_p }});
}
})
}
Views.py
elif request.method == "GET":
owned_license_id = request.GET.get('id', '')
form = OwnedLicenseForm(owned_license_id)
return form
I see what you are trying to do, but you cannot render the html form this way:
$("#formdiv").html({{ response.as_p }});
I think you are confusing server side rendering (Django templates) with client side rendering. Server side rendering happens when your server is processing the request, it cannot render objects produced by javascript running in the browser.
Because response is a javascript object, obtained by jquery sending an Ajax request to your url. At this time, the page has already been rendered by Django's template engine, and sent to the browser. There is no way for Django template to even be aware of this response.
I understand you want to use the as_p() method to render the form, you can do it like this:
function get_edit_form(button, id)
{
$.ajax({
url: "/manage/licenses/{{mls_signup_code}}/{{agent_id}}/" + id + "/",
type: "get",
data: {id: id},
success: function(response) {
console.log(response);
// response is form in html format
$("#formdiv").html(response);
}
})
}
# Views.py
elif request.method == "GET":
owned_license_id = request.GET.get('id', '')
form = OwnedLicenseForm(owned_license_id)
return HttpResponse(form.as_p()) # return a html str
You can accomplish this with a combination of Django and JQuery.
Step 1: Create an ultra simple form_from_ajax.html Template
The template can be as simple as {{form.as_p}}. The point is to not inherit your base template. You're simply using this form_from_ajax.html template to render the HTML of the form.
Step 2: Create a View with a slug argument that helps you get the correct form
def payment_method_ajax(request, method): # method is your slug
"""Load a dynamic form based on the desired payment method"""
options = {
'ach': ECheckForm(), # Dynamic form #1
'credit-card': CreditCardForm(), # Dynamic form #2
}
if method in options.keys():
context = {'form': options[method]}
else:
context = None
template = 'your_app_name/form_from_ajax.html'
return render(request, template, context)
Step 3: Define the AJAX url in urls.py
[...
path(
'payment-method-ajax/<slug:method>/', # notice the slug in the URL
views.payment_method_ajax,
name='payment-method-ajax'),
...]
Step 4: Update your template where you'd like the AJAX loaded form to appear
Make some buttons to have the user select an approprate form option
<button id="btn_ach" onclick="load_payment_form(this)">ACH</button>
<button id="btn_credit_card" onclick="load_payment_form(this)">Credit Card</button>
form-fields is where the dynamic form will be loaded
<form id="id-form" style="display: none;">
{% csrf_token %}
<div id="form-fields"></div>
<input type="submit" value="Save Payment Details"/>
</form>
Make sure to add slugs to your main view's context
context = {
'target': 'Add a New Payment Method',
'h1': 'Add a New Payment Method',
'ach': 'Save an ACH Profile',
'credit_card': 'Save a Credit Card Profile',
'slugs': ['ach', 'credit-card'], # Here are the slugs ****
}
Step 5: Load the form with JQuery and the button's onclick
<script>
var ach = 'ACH';
var creditCard = 'Credit Card';
var form_urls ={
ach : '{% url "payment-method-ajax" slugs.0 %}',
creditCard : '{% url "payment-method-ajax" slugs.1 %}',
}
function load_payment_form(btn) {
if(btn.innerText==ach) {
get_url = form_urls['ach'];
type = ach;
}
else if(btn.innerText==creditCard) {
console.log('Load credit card form');
get_url = form_urls['creditCard'];
type = creditCard;
}
$.get({'url': get_url}).done(
function(data) {
document.getElementById('form-fields').innerHTML = data;})
document.getElementById("id-form").style.display = "block";
}
</script>