django and dropzone how to post form - python

I have gone through django and dropzone. I have implemented drag and drop feature of dropzone in django.
My template look like:
<form id="add-multiple" class="dropzone" action="{% url "name_add" %}" method="post" enctype="multipart/form-data">
{% csrf_token %}
</form>
<button id="submit-all" type="submit" value="Submit" form="add-multiple">
Submit all files
</button>
<script src="{% static 'js/dropzone.js' %}"></script>
<script type="text/javascript">
Dropzone.options.myDropzone = {
// Prevents Dropzone from uploading dropped files immediately
autoProcessQueue : false,
paramName: "files",
init : function() {
var submitButton = document.querySelector("#submit-all")
myDropzone = this;
submitButton.addEventListener("click", function() {
myDropzone.processQueue();
// Tell Dropzone to process all queued files.
});
// You might want to show the submit button only when
// files are dropped here:
this.on("addedfile", function() {
// Show submit button here and/or inform user to click it.
});
}
};
</script>
Here, I am getting the css and uploading perfectly, but when I submit the form, it doesn't call the {% url "name_add" %} url. I mean, the form is not posted and it doesn't call that url.
I followed this tutorial https://amatellanes.wordpress.com/2013/11/05/dropzonejs-django-how-to-build-a-file-upload-form/ to achieve this.
First thing, my form is not being posted or it says it is not calling the url in form action. Second there is not any use of my form that I have created in forms.py to upload a file. In the tutorial also there is no use of form. Why is that and without form how form can be submitted because view requires form.
Can anyone help me?

in:
Dropzone.options.myDropzone = {
....
actually myDropzone is the camelized version of the HTML element's ID.
so the form id must be my_dropzone instead of add-multiple:
<form id="my_dropzone" class="dropzone" action...

Related

Problem with updating an already updated html dom with Flask

I have a flask dropzone to upload files.
Once an upload is done I want to print a log text on the html site
It works so far, the only problem is - the div tag doesn't update the log text after the second upload. The website stays with the text from the first upload.
index.html:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<script>
$(function(){
window.setInterval(function() {
loadNewLogger()
}, 500)
function loadNewLogger(){
$.ajax({
url:"/write_log",
type: "POST",
datatype: "json",
success: function(data){
$(logger).replaceWith(data)
}
});
}
});
</script>
<body>
<div style="color:rgb(0, 0, 0);text-align:center">
CDR PIPELINE </div>
{{ dropzone.create(action='upload') }}
{{ dropzone.load_js() }}
{{ dropzone.config() }}
<div id="logger">
{{ logger }}
</div>
</body>
</html>
logger.html (otherwise I would render index.html twice)
<div id="logger">
{{ logger }}
</div>
excerpt from flask_app.py:
#app.route('/',methods=['POST','GET'])
def upload():
if request.method == 'POST':
f = request.files.get('file')
f.save(os.path.join(app.config['UPLOADED_PATH'],f.filename))
upload.logger = ""
es.main()
upload.logger = es.main.result
return upload.logger
return render_template('index.html')
#app.route('/write_log',methods=['POST'])
def log():
logger = upload.logger
return jsonify('', render_template('logger.html', logger=logger))
Why is it updating the text from upload.logger only once?
First of all, instead of JQuery AJAX, I would recommend using PHP. For example, when you upload files from index.html you can redirect to upload.php, and you can display the message using "echo"
But even if you aren't comfortable with that, don't get too much into Python or JQuery. Your problem can very easily be solved with plain JavaScript:
Here is your html element in logger.html:
<div id="logger"></div>
In flask app.py:
document.getElementById("logger").innerHTML="Your message to be displayed"
I would also recommend you to remove setinterval in index.html as people don't like dynamically reloading blocks

[Django]How to display a message(correct or incorrect) after submitting the form, without refreshing the page?

I have a made a quiz page, which checks whether the answer of the user is correct or not using a "checkans" function. I want to return a "Correct" message if the answer is correct and an "Incorrect" message if the answer is not correct. Now I can "kind of" do it, but not exactly what I want. Now it returns the message after redirecting to a whole new page, with the Question Box and everything else totally disappeared, only with the message.
I want the message to be shown on the same original question page, somewhere under the question box or within the question box, without redirecting to another page or refreshing the page, after submitting the answer. I don't know how to do it.
Here is my view:
class QuizView(generic.ListView):
template_name = 'geniusdennis/quiz.html'
queryset = Spanish.objects.all()
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
# grab the max id in the database
max_id = Spanish.objects.order_by('-id')[0].id
random_id = random.randint(1, max_id + 1)
random_spanish_question = Spanish.objects.filter(id__gte=random_id)[0]
context['random_spanish_question'] = random_spanish_question
return context
Here is my function for checking the answer:
def checkans(request, spanish_id):
random_spanish_question = get_object_or_404(Spanish, pk=spanish_id)
query = request.GET.get('ans')
coreng = random_spanish_question.english_set.get()
if query == str(coreng):
return render(request, 'geniusdennis/quiz.html',{
'message': "Correct!",
})
else:
return render(request, 'geniusdennis/quiz.html', {
'message': "Incorrect.",
'correct_answer': "The correct answer is " + str(coreng),
})
And here is my HTML page:
{% load static %}
<link rel="stylesheet" type="text/css" href="{% static 'geniusdennis/style.css' %}">
{% if random_spanish_question %}
<div class="flexcontainer" style="justify-content: center;">
<div class="sectiontitle">Quiz time
</div>
<div class="question_card">
<div class="question_word">{{ random_spanish_question }}</div>
<form action="/checkans/{{random_spanish_question.id}}/" method="get">{% csrf_token %}
<label for="ans">Answer:</label>
<input type="text" name="ans"/>
<input type="submit" value="Submit"/>
</form>
<input type="submit" value="Skip"/>
</div>
</div>
{% else %}
{% if message %}
<div class="message">
{{ message }}
</div>
<div class="ans">
{{ correct_answer }}
</div>
{% endif %}
{% endif %}
What you need is ajax, so you need some js code here.
<scrip src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script>
$('form').on('submit', function(e) { // or you can get the form by id if you set it
e.preventDefault(); // avoid to execute the actual submit of the form.
var form = $(this);
var url = form.attr('action');
$.ajax({
type: 'GET',
url: url,
data: form.serialize(), // serializes the forms elements.
success: function(data)
{
... // whatever you want to do
var alertMessage = data.message;
if (data.correct_answer) {
alertMessage += ' ' + data.correct_answer;
}
alert(alertMessage); // show response
}
});
});
</script>
html forms will go to action url. If you want some changes or functions in your page without reload, you need to use js.
Quite commonly in web applications, you need to display a one-time
notification message (also known as “flash message”) to the user after
processing a form or some other types of user input.
For this, Django provides full support for cookie- and session-based
messaging, for both anonymous and authenticated users. The messages
framework allows you to temporarily store messages in one request and
retrieve them for display in a subsequent request (usually the next
one). Every message is tagged with a specific level that determines
its priority (e.g., info, warning, or error).
for implementing messages refer to: https://docs.djangoproject.com/en/1.11/ref/contrib/messages/

POST 404 (NOT FOUND)

i am getting a 404 error when submitting a form. I try to upload a .png through that form and submit it right after the upload. Then the Server (Python, Flask) should be able to work with that. Does anyone know where my issue is?
AJAX:
<script>
document.getElementById("exampleFormControlFile1").onchange = function() {
console.log("Came here");
$.ajax({
url:'/uploadPNG/',
type:'post',
data:$('#exampleFormControlFile1').serialize(),
success:function(){
console.log("Came here");
}
});
};
</script>
HTML:
<form method="POST" id="form">
<div class="form-group">
<label for="exampleFormControlFile1">Upload your .png template</label>
<input type="file" class="form-control-file" id="exampleFormControlFile1">
</div>
</form>
SERVER:
#app.route('/uploadPNG/', methods=['POST'])
def upload():
if request.method == 'POST':
print("Got png")
return "gotcha"
Thank you in advance
I just figured out the issue. Gonna answer my own post here so that others may have it easier.
A magic wizard once told me to always check the documentation.
http://flask.pocoo.org/docs/1.0/patterns/fileuploads/
Then I had to adjust the AJAX call like here:
'append' called on an object that does not implement interface FormData
And then i had to add the name "file" to the input tag.

POST vs GET method in Django's view function

My app's urls.py is:
from django.urls import path
from . import views
app_name = 'javascript'
urlpatterns = [
path('create_table', views.create_table, name='create_table')
My views.py is:
def create_table(request):
if request.method == 'POST':
row_data = "this is row data"
context = {'row_data': row_data}
return render(request, 'javascript/create_table.html',context)
My create_table.html is:
{% load static %}
<form action="" method="post">
{% csrf_token %}
<button id="create_table">Get data</button>
</form>
<div id="place_for_table"></div>
<script type="text/javascript">
var row_data = "{{ row_data }}"
</script>
<script src="{% static 'javascript/scripts/create_table.js' %}"></script>
And my create_table.js is:
function create_table() {
document.getElementById("place_for_table").innerHTML = row_data;
}
document.getElementById("create_table").onclick = function() {
create_table()
}
What I want to achieve is: when the /create table URL is requested, only the button is displayed. When the button is pressed, row_data variable's value is displayed below the button.
At this moment the data is displayed for a blink of an eye and then disappears.
I guess I am not distinguishing between POST and GET methods correctly in the view function. Also I have based my logic on the assumption that URL is requested using GET method by default. However if I put a print(request.method) at the beginning of my view, it prints POST.
Also, whenever I load the page for the first time or refresh it, I get a Firefox warning:"To display this page, Firefox must send information that will repeat any action (such as a search or order confirmation) that was performed earlier."
Other things I tried was to use class-based view with post and get defs or put the create_table's URL in button formaction= tag, but that doesn't help.
I would be thankful for any suggestions on how to achieve this.
The problem might be because when you are submitting the form it refreshes/reloads your page i.e. /create_table url because of which row_data resets
This Might help you to understand why the button submits even though you didn't explicitly provided type="submit" to the button inside your form.
Our aim will be to prevent the event to occur. It can be done using a simple return false statement in our onclick listener as given below:
function create_table() {
document.getElementById("place_for_table").innerHTML = row_data;
}
document.getElementById("create_table").onclick = function(event) {
create_table();
return false;
}

How to add alert popup boxes in django?

I've been going through the django documentation, but so far everything I've tried hasn't worked for me. I'm trying to make it so if the user enters the url to a certain page and they are not already logged in then they are redirected to the login page that gives them a popup error message that says they don't have access to the page until they have logged in.
Here is a small snippet of code from the views.py
def home(request):
if request.session.test_cookie_worked():
return render(request, 'page/home.html')
else:
return render(request, 'page/login.html')
Everything works except for the error message not popping up if they are redirected to the login page. I've looked at other stack overflow questions that people have asked that are similar to this, but those don't seem to work for me either. Any advice?
Here's how I'm doing it.
First, if the view code determines that the popup should be displayed, call render() with a named flag in the context:
return render(request, 'page/home.html', {'some_flag': True})
Then, in your page template, if the flag is set, display a <div> element:
{% if some_flag %}
<div id="some_flag" title="Some Flag">
<p>Some Text Here</p>
</div>
{% endif %}
Also in the page template, in the <head> section, create a JavaScript function to display the <div> as a popup dialog:
<head>
<script type="text/javascript">
$(document).ready(function() {
$(function() {
$( "#some_flag" ).dialog({
modal: true,
closeOnEscape: false,
dialogClass: "no-close",
resizable: false,
draggable: false,
width: 600,
buttons: [
{
text: "OK",
click: function() {
$( this ).dialog( "close" );
}
}
]
});
});
});
</script>
</head>
This solution also requires that you use the jQuery library.
I'm sure there are drawbacks to doing it this way, but it works for me.
We can pass a variable in context object like a flag.
return render(request, 'index.html', {'alert_flag': True})
and then in templates simply do a check for the alert_flag.
{% if alert_flag %}
<script>alert("Some Message.")</script>
{% endif %}
Here no jQuery code is required and I am using native alert.

Categories